Repository: Hjorthmedh/Snudda (language: python)

Issue:
Connectivity



Discussion / hints:

Fix patch:
diff --git a/examples/notebooks/Parkinson/WT2PD_example.ipynb b/examples/notebooks/Parkinson/WT2PD_example.ipynb
new file mode 100644
index 000000000..f381bfc74
--- /dev/null
+++ b/examples/notebooks/Parkinson/WT2PD_example.ipynb
@@ -0,0 +1,2394 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "7c92eaab",
+   "metadata": {},
+   "source": [
+    "This notebook creates a WT network, then swappes the WT morphologies in the network file for degenerated PD morphologies where part of the dendrites have been removed. The synapses and inputs on the degenerated parts of the morphologies are automatically removed."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "14c39178",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Using cube for striatum\n",
+      "Neurons for striatum read from /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum\n",
+      "Adding neurons: FS from dir /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/0/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/0/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/1/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/1/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/3/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/3/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/2/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/2/mechanisms.json\n",
+      "Adding neurons: dSPN from dir /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/32/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/32/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/35/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/35/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/34/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/34/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/33/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/33/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/20/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/20/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/18/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/18/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/27/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/27/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/9/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/9/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/0/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/0/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/11/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/11/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/7/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/7/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/29/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/29/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/16/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/16/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/6/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/6/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/28/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/28/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/17/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/17/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/1/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/1/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/10/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/10/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/19/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/19/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/26/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/26/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/8/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/8/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/21/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/21/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/31/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/31/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/30/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/30/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/24/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/24/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/23/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/23/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/4/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/4/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/15/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/15/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/3/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/3/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/12/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/12/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/2/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/2/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/13/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/13/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/5/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/5/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/14/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/14/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/22/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/22/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/25/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/25/mechanisms.json\n",
+      "Adding neurons: iSPN from dir /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "No parameter.json file.\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/32/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/32/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/35/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/35/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/34/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/34/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/33/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/33/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/20/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/20/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/18/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/18/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/27/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/27/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/9/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/9/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/0/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/0/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/11/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/11/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/7/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/7/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/29/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/29/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/16/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/16/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/6/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/6/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/28/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/28/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/17/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/17/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/1/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/1/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/10/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/10/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/19/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/19/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/26/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/26/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/8/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/8/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/21/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/21/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/31/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/31/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/30/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/30/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/24/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/24/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/23/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/23/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/4/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/4/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/15/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/15/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/3/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/3/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/12/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/12/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/2/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/2/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/13/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/13/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/5/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/5/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/14/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/14/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/22/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/22/mechanisms.json\n",
+      "Parameter file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/25/parameters.json\n",
+      "Mechanism file not found: /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/25/mechanisms.json\n",
+      "Writing WT-network/network-config.json\n"
+     ]
+    }
+   ],
+   "source": [
+    "import os\n",
+    "from snudda.init import SnuddaInit\n",
+    "\n",
+    "# Future location\n",
+    "SNUDDA_DATA_WT = os.path.join(\"..\", \"..\", \"..\", \"..\", \"BasalGangliaData/Parkinson/20211105/PD0\")\n",
+    "SNUDDA_DATA_PD2 = os.path.join(\"..\", \"..\", \"..\", \"..\", \"BasalGangliaData/Parkinson/20211105/PD2\")\n",
+    "\n",
+    "# My local copy with next version from Alex\n",
+    "SNUDDA_DATA_WT = \"/media/psf/KTH/PD20220225/parkinson/20220225/pd0\"\n",
+    "SNUDDA_DATA_PD2 = \"/media/psf/KTH/PD20220225/parkinson/20220225/pd2\"\n",
+    "\n",
+    "os.environ[\"SNUDDA_DATA\"] = SNUDDA_DATA_WT\n",
+    "network_path_WT = \"WT-network\"\n",
+    "network_path_PD2 = \"PD2-network\"\n",
+    "\n",
+    "si = SnuddaInit(struct_def={}, network_path=network_path_WT, random_seed=123)\n",
+    "si.define_striatum(num_dSPN=200, num_iSPN=200, num_FS=4, num_LTS=0, num_ChIN=0,\n",
+    "                    volume_type=\"cube\")\n",
+    "si.write_json()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "6299ab29",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Warning, running in serial.\n"
+     ]
+    }
+   ],
+   "source": [
+    "from ipyparallel import Client\n",
+    "\n",
+    "os.environ[\"IPYTHONDIR\"] = \".ipython\"\n",
+    "os.environ[\"IPYTHON_PROFILE\"] = \"default\"\n",
+    "\n",
+    "u_file = os.path.join(os.getcwd(), \".ipython\", \"profile_default\", \"security\", \n",
+    "                      \"ipcontroller-client.json\")\n",
+    "if os.path.exists(u_file):\n",
+    "    rc = Client(url_file=u_file, timeout=120, debug=False)\n",
+    "else:\n",
+    "    print(\"Warning, running in serial.\")\n",
+    "    rc = None"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "0f62d8b2",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/0/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/1/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/3/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/2/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/32/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/35/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/34/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/33/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/20/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/18/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/27/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/9/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/0/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/11/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/7/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/29/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/16/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/6/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/28/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/17/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/1/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/10/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/19/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/26/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/8/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/21/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/31/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/30/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/24/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/23/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/4/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/15/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/3/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/12/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/2/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/13/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/5/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/14/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/22/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/25/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/32/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/35/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/34/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/33/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/20/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/18/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/27/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/9/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/0/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/11/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/7/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/29/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/16/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/6/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/28/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/17/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/1/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/10/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/19/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/26/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/8/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/21/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/31/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/30/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/24/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/23/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/4/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/15/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/3/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/12/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/2/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/13/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/5/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/14/parameters.json\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/22/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/25/parameters.json\n"
+     ]
+    }
+   ],
+   "source": [
+    "from snudda import SnuddaPlace\n",
+    "sp = SnuddaPlace(network_path=network_path_WT, rc=rc)\n",
+    "sp.place()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "id": "2a69fef0",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/0/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/1/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/3/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/2/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/32/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/35/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/34/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/33/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/20/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/18/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/27/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/9/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/0/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/11/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/7/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/29/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/16/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/6/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/28/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/17/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/1/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/10/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/19/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/26/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/8/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/21/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/31/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/30/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/24/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/23/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/4/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/15/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/3/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/12/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/2/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/13/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/5/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/14/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/22/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/25/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/32/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/35/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/34/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/33/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/20/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/18/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/27/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/9/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/0/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/11/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/7/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/29/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/16/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/6/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/28/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/17/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/1/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/10/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/19/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/26/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/8/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/21/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/31/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/30/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/24/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/23/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/4/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/15/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/3/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/12/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/2/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/13/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/5/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/14/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/22/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/25/parameters.json\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "No d_view specified, running distribute neurons in serial\n",
+      "Processing hyper voxel : 41/180 (404 neurons)\n",
+      "Processing hyper voxel : 36/180 (391 neurons)\n",
+      "Processing hyper voxel : 42/180 (368 neurons)\n",
+      "Processing hyper voxel : 71/180 (329 neurons)\n",
+      "Processing hyper voxel : 37/180 (320 neurons)\n",
+      "Processing hyper voxel : 66/180 (275 neurons)\n",
+      "Processing hyper voxel : 72/180 (228 neurons)\n",
+      "Processing hyper voxel : 11/180 (184 neurons)\n",
+      "Processing hyper voxel : 67/180 (171 neurons)\n",
+      "Processing hyper voxel : 40/180 (167 neurons)\n",
+      "Processing hyper voxel : 6/180 (148 neurons)\n",
+      "Processing hyper voxel : 46/180 (105 neurons)\n",
+      "Processing hyper voxel : 12/180 (102 neurons)\n",
+      "Processing hyper voxel : 35/180 (101 neurons)\n",
+      "Processing hyper voxel : 7/180 (92 neurons)\n",
+      "Processing hyper voxel : 70/180 (73 neurons)\n",
+      "Processing hyper voxel : 65/180 (52 neurons)\n",
+      "Processing hyper voxel : 47/180 (52 neurons)\n",
+      "Processing hyper voxel : 76/180 (41 neurons)\n",
+      "Processing hyper voxel : 31/180 (30 neurons)\n",
+      "Processing hyper voxel : 10/180 (28 neurons)\n",
+      "Processing hyper voxel : 16/180 (25 neurons)\n",
+      "Processing hyper voxel : 77/180 (20 neurons)\n",
+      "Processing hyper voxel : 43/180 (19 neurons)\n",
+      "Processing hyper voxel : 61/180 (18 neurons)\n",
+      "Processing hyper voxel : 5/180 (16 neurons)\n",
+      "Processing hyper voxel : 38/180 (15 neurons)\n",
+      "Processing hyper voxel : 32/180 (13 neurons)\n",
+      "Processing hyper voxel : 45/180 (11 neurons)\n",
+      "Processing hyper voxel : 101/180 (9 neurons)\n",
+      "Processing hyper voxel : 17/180 (9 neurons)\n",
+      "Processing hyper voxel : 62/180 (6 neurons)\n",
+      "Processing hyper voxel : 96/180 (6 neurons)\n",
+      "Processing hyper voxel : 1/180 (5 neurons)\n",
+      "Processing hyper voxel : 30/180 (4 neurons)\n",
+      "Processing hyper voxel : 15/180 (3 neurons)\n",
+      "Processing hyper voxel : 2/180 (3 neurons)\n",
+      "Processing hyper voxel : 73/180 (3 neurons)\n",
+      "Processing hyper voxel : 97/180 (3 neurons)\n",
+      "Processing hyper voxel : 48/180 (3 neurons)\n",
+      "Processing hyper voxel : 60/180 (2 neurons)\n",
+      "Processing hyper voxel : 102/180 (2 neurons)\n",
+      "Processing hyper voxel : 8/180 (2 neurons)\n",
+      "Processing hyper voxel : 100/180 (2 neurons)\n",
+      "Processing hyper voxel : 18/180 (2 neurons)\n",
+      "Processing hyper voxel : 106/180 (1 neurons)\n",
+      "Processing hyper voxel : 95/180 (1 neurons)\n",
+      "Processing hyper voxel : 0/180 (1 neurons)\n",
+      "Processing hyper voxel : 91/180 (1 neurons)\n",
+      "Processing hyper voxel : 81/180 (1 neurons)\n",
+      "Processing hyper voxel : 75/180 (1 neurons)\n",
+      "Processing hyper voxel : 68/180 (1 neurons)\n",
+      "Processing hyper voxel : 51/180 (1 neurons)\n",
+      "Processing hyper voxel : 107/180 (1 neurons)\n",
+      "Processing hyper voxel : 13/180 (1 neurons)\n",
+      "Processing hyper voxel : 92/180 (1 neurons)\n",
+      "Processing hyper voxel : 127/180 (1 neurons)\n"
+     ]
+    }
+   ],
+   "source": [
+    "from snudda import SnuddaDetect\n",
+    "\n",
+    "sd = SnuddaDetect(network_path=network_path_WT, rc=rc)\n",
+    "sd.detect()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "id": "cfa8830a",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Worker synapses: 10/1483661 (heap size: 18)\n",
+      "Worker synapses: 1483661/1483661 (heap size: 0)\n",
+      "Read 1483661 out of total 1483661 synapses\n",
+      "Read 35 out of total 35 gapJunctions\n"
+     ]
+    }
+   ],
+   "source": [
+    "from snudda import SnuddaPrune\n",
+    "\n",
+    "sp = SnuddaPrune(network_path=network_path_WT, rc=rc)\n",
+    "sp.prune()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "id": "b0141e53",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Loading 404 neurons with 73718 synapses and 20 gap junctions\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/7/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/28/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/34/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/27/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/17/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/22/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/17/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/24/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/33/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/10/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/21/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/29/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/7/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/32/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/4/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/23/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/1/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/13/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/33/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/8/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/12/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/26/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/2/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/18/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/4/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/14/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/26/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/29/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/19/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/24/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/12/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/32/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/3/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/25/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/22/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/0/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/35/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/6/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/15/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/23/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/13/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/6/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/30/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/21/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/30/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/35/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/20/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/31/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/2/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/19/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/1/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/31/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/18/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/27/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/11/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/8/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/3/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/14/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/34/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/11/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/28/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/5/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/25/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/15/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/9/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/0/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/16/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/16/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/1/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/20/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/10/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/5/parameters.json\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/3/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/0/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/9/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/2/parameters.json\n",
+      "Writing spikes to WT-network/input-spikes.hdf5\n"
+     ]
+    }
+   ],
+   "source": [
+    "import os\n",
+    "from snudda.input import SnuddaInput\n",
+    "si = SnuddaInput(network_path=network_path_WT, \n",
+    "                 input_config_file=\"dummy-input.json\",   # This file does NOT have correct synapse parameters\n",
+    "                 verbose=False)\n",
+    "si.generate()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "id": "f96a2176",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "original_network_file = os.path.join(network_path_WT, \"network-synapses.hdf5\")\n",
+    "original_input_file = os.path.join(network_path_WT, \"input-spikes.hdf5\")\n",
+    "\n",
+    "new_network_file = os.path.join(network_path_PD2, \"network-synapses.hdf5\")\n",
+    "new_input_file = os.path.join(network_path_PD2, \"input-spikes.hdf5\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "id": "a719738a",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Loading 404 neurons with 73718 synapses and 20 gap junctions\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/7/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/7/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/28/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/28/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/34/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/34/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/27/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/27/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/17/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/17/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/22/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/22/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/17/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/17/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/24/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/24/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/33/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/33/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/10/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/10/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/21/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/21/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/29/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/29/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/7/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/7/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/32/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/32/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/4/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/4/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/23/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/23/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/1/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/1/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/13/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/13/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/33/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/33/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/8/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/8/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/12/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/12/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/26/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/26/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/2/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/2/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/18/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/18/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/4/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/4/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/14/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/14/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/26/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/26/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/29/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/29/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/19/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/19/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/24/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/24/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/12/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/12/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/32/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/32/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/3/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/3/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/25/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/25/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/22/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/22/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/0/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/0/parameters.json\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/35/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/35/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/6/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/6/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/15/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/15/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/23/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/23/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/13/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/13/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/6/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/6/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/30/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/30/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/21/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/21/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/30/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/30/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/35/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/35/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/20/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/20/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/31/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/31/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/2/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/2/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/19/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/19/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/1/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/1/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/31/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/31/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/18/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/18/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/27/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/27/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/11/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/11/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/8/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/8/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/3/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/3/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/14/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/14/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/34/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/34/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/11/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/11/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/28/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/28/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/5/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/5/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/25/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/25/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/15/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/15/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/9/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/9/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/0/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/0/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/16/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/16/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/16/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/16/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/1/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/20/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/20/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/10/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/10/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/5/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/5/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/3/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/0/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/ispn/9/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/ispn/9/parameters.json\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/fs/2/parameters.json\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Writing new network to PD2-network/network-synapses.hdf5\n",
+      "10000 / 73718\n",
+      "20000 / 73718\n",
+      "30000 / 73718\n",
+      "40000 / 73718\n",
+      "50000 / 73718\n",
+      "60000 / 73718\n",
+      "70000 / 73718\n",
+      "73718 / 73718\n",
+      "Keeping 37191 out of 73718 synapses (50.450 %)\n",
+      "20 / 20\n",
+      "Keeping 19 out of 20 gap junctions (95.000 %)\n",
+      "Writing new input data to PD2-network/input-spikes.hdf5\n",
+      "Processed input to dSPN_10 (0), keeping 267 out of 474 inputs (56.33 %)\n",
+      "Processed input to dSPN_14 (1), keeping 235 out of 438 inputs (53.65 %)\n",
+      "Processed input to iSPN_21 (10), keeping 215 out of 360 inputs (59.72 %)\n",
+      "Processed input to iSPN_22 (100), keeping 108 out of 237 inputs (45.57 %)\n",
+      "Processed input to iSPN_24 (101), keeping 89 out of 249 inputs (35.74 %)\n",
+      "Processed input to dSPN_2 (102), keeping 213 out of 325 inputs (65.54 %)\n",
+      "Processed input to dSPN_22 (103), keeping 123 out of 309 inputs (39.81 %)\n",
+      "Processed input to dSPN_22 (104), keeping 130 out of 340 inputs (38.24 %)\n",
+      "Processed input to dSPN_24 (105), keeping 76 out of 346 inputs (21.97 %)\n",
+      "Processed input to dSPN_32 (106), keeping 222 out of 432 inputs (51.39 %)\n",
+      "Processed input to iSPN_2 (107), keeping 69 out of 100 inputs (69.00 %)\n",
+      "Processed input to dSPN_18 (108), keeping 272 out of 584 inputs (46.58 %)\n",
+      "Processed input to dSPN_35 (109), keeping 379 out of 658 inputs (57.60 %)\n",
+      "Processed input to dSPN_11 (11), keeping 176 out of 386 inputs (45.60 %)\n",
+      "Processed input to iSPN_11 (110), keeping 150 out of 274 inputs (54.74 %)\n",
+      "Processed input to iSPN_19 (111), keeping 57 out of 193 inputs (29.53 %)\n",
+      "Processed input to iSPN_28 (112), keeping 112 out of 189 inputs (59.26 %)\n",
+      "Processed input to dSPN_20 (113), keeping 44 out of 217 inputs (20.28 %)\n",
+      "Processed input to dSPN_31 (114), keeping 101 out of 343 inputs (29.45 %)\n",
+      "Processed input to iSPN_20 (115), keeping 39 out of 118 inputs (33.05 %)\n",
+      "Processed input to iSPN_27 (116), keeping 58 out of 175 inputs (33.14 %)\n",
+      "Processed input to dSPN_7 (117), keeping 188 out of 428 inputs (43.93 %)\n",
+      "Processed input to dSPN_8 (118), keeping 141 out of 365 inputs (38.63 %)\n",
+      "Processed input to dSPN_12 (119), keeping 330 out of 561 inputs (58.82 %)\n",
+      "Processed input to iSPN_10 (12), keeping 148 out of 217 inputs (68.20 %)\n",
+      "Processed input to dSPN_14 (120), keeping 248 out of 464 inputs (53.45 %)\n",
+      "Processed input to iSPN_3 (121), keeping 114 out of 290 inputs (39.31 %)\n",
+      "Processed input to dSPN_3 (122), keeping 68 out of 220 inputs (30.91 %)\n",
+      "Processed input to dSPN_16 (123), keeping 182 out of 399 inputs (45.61 %)\n",
+      "Processed input to dSPN_27 (124), keeping 55 out of 300 inputs (18.33 %)\n",
+      "Processed input to dSPN_3 (125), keeping 86 out of 220 inputs (39.09 %)\n",
+      "Processed input to dSPN_7 (126), keeping 172 out of 397 inputs (43.32 %)\n",
+      "Processed input to iSPN_6 (127), keeping 162 out of 286 inputs (56.64 %)\n",
+      "Processed input to iSPN_31 (128), keeping 69 out of 190 inputs (36.32 %)\n",
+      "Processed input to iSPN_33 (129), keeping 170 out of 272 inputs (62.50 %)\n",
+      "Processed input to dSPN_0 (13), keeping 85 out of 135 inputs (62.96 %)\n",
+      "Processed input to iSPN_34 (130), keeping 132 out of 298 inputs (44.30 %)\n",
+      "Processed input to dSPN_35 (131), keeping 357 out of 632 inputs (56.49 %)\n",
+      "Processed input to dSPN_14 (132), keeping 243 out of 449 inputs (54.12 %)\n",
+      "Processed input to dSPN_33 (133), keeping 301 out of 533 inputs (56.47 %)\n",
+      "Processed input to iSPN_8 (134), keeping 91 out of 173 inputs (52.60 %)\n",
+      "Processed input to dSPN_25 (135), keeping 348 out of 629 inputs (55.33 %)\n",
+      "Processed input to dSPN_32 (136), keeping 231 out of 458 inputs (50.44 %)\n",
+      "Processed input to iSPN_0 (137), keeping 99 out of 150 inputs (66.00 %)\n",
+      "Processed input to iSPN_28 (138), keeping 126 out of 208 inputs (60.58 %)\n",
+      "Processed input to dSPN_18 (139), keeping 247 out of 532 inputs (46.43 %)\n",
+      "Processed input to dSPN_26 (14), keeping 71 out of 290 inputs (24.48 %)\n",
+      "Processed input to dSPN_26 (140), keeping 104 out of 326 inputs (31.90 %)\n",
+      "Processed input to dSPN_30 (141), keeping 95 out of 318 inputs (29.87 %)\n",
+      "Processed input to iSPN_0 (142), keeping 93 out of 150 inputs (62.00 %)\n",
+      "Processed input to iSPN_12 (143), keeping 171 out of 305 inputs (56.07 %)\n",
+      "Processed input to iSPN_21 (144), keeping 244 out of 390 inputs (62.56 %)\n",
+      "Processed input to FS_1 (145), keeping 522 out of 545 inputs (95.78 %)\n",
+      "Processed input to dSPN_15 (146), keeping 19 out of 244 inputs (7.79 %)\n",
+      "Processed input to dSPN_20 (147), keeping 34 out of 198 inputs (17.17 %)\n",
+      "Processed input to dSPN_23 (148), keeping 294 out of 514 inputs (57.20 %)\n",
+      "Processed input to dSPN_29 (149), keeping 283 out of 516 inputs (54.84 %)\n",
+      "Processed input to iSPN_10 (15), keeping 152 out of 239 inputs (63.60 %)\n",
+      "Processed input to dSPN_33 (150), keeping 322 out of 556 inputs (57.91 %)\n",
+      "Processed input to dSPN_7 (151), keeping 193 out of 430 inputs (44.88 %)\n",
+      "Processed input to dSPN_34 (152), keeping 126 out of 400 inputs (31.50 %)\n",
+      "Processed input to dSPN_34 (153), keeping 119 out of 405 inputs (29.38 %)\n",
+      "Processed input to iSPN_1 (154), keeping 47 out of 155 inputs (30.32 %)\n",
+      "Processed input to iSPN_9 (155), keeping 89 out of 209 inputs (42.58 %)\n",
+      "Processed input to iSPN_23 (156), keeping 214 out of 342 inputs (62.57 %)\n",
+      "Processed input to dSPN_4 (157), keeping 163 out of 437 inputs (37.30 %)\n",
+      "Processed input to dSPN_9 (158), keeping 140 out of 364 inputs (38.46 %)\n",
+      "Processed input to dSPN_17 (159), keeping 222 out of 446 inputs (49.78 %)\n",
+      "Processed input to iSPN_17 (16), keeping 129 out of 233 inputs (55.36 %)\n",
+      "Processed input to dSPN_27 (160), keeping 42 out of 271 inputs (15.50 %)\n",
+      "Processed input to iSPN_2 (161), keeping 57 out of 100 inputs (57.00 %)\n",
+      "Processed input to iSPN_32 (162), keeping 111 out of 198 inputs (56.06 %)\n",
+      "Processed input to dSPN_2 (163), keeping 204 out of 325 inputs (62.77 %)\n",
+      "Processed input to dSPN_18 (164), keeping 282 out of 556 inputs (50.72 %)\n",
+      "Processed input to dSPN_33 (165), keeping 284 out of 547 inputs (51.92 %)\n",
+      "Processed input to iSPN_1 (166), keeping 54 out of 155 inputs (34.84 %)\n",
+      "Processed input to dSPN_2 (167), keeping 214 out of 325 inputs (65.85 %)\n",
+      "Processed input to iSPN_9 (168), keeping 88 out of 189 inputs (46.56 %)\n",
+      "Processed input to iSPN_18 (169), keeping 201 out of 334 inputs (60.18 %)\n",
+      "Processed input to iSPN_25 (17), keeping 259 out of 385 inputs (67.27 %)\n",
+      "Processed input to dSPN_19 (170), keeping 55 out of 306 inputs (17.97 %)\n",
+      "Processed input to dSPN_20 (171), keeping 46 out of 239 inputs (19.25 %)\n",
+      "Processed input to dSPN_32 (172), keeping 205 out of 408 inputs (50.25 %)\n",
+      "Processed input to iSPN_0 (173), keeping 97 out of 150 inputs (64.67 %)\n",
+      "Processed input to dSPN_0 (174), keeping 79 out of 135 inputs (58.52 %)\n",
+      "Processed input to dSPN_12 (175), keeping 342 out of 578 inputs (59.17 %)\n",
+      "Processed input to dSPN_31 (176), keeping 101 out of 323 inputs (31.27 %)\n",
+      "Processed input to iSPN_8 (177), keeping 101 out of 174 inputs (58.05 %)\n",
+      "Processed input to iSPN_18 (178), keeping 212 out of 364 inputs (58.24 %)\n",
+      "Processed input to iSPN_31 (179), keeping 67 out of 176 inputs (38.07 %)\n",
+      "Processed input to iSPN_34 (18), keeping 134 out of 297 inputs (45.12 %)\n",
+      "Processed input to dSPN_3 (180), keeping 68 out of 220 inputs (30.91 %)\n",
+      "Processed input to dSPN_23 (181), keeping 289 out of 485 inputs (59.59 %)\n",
+      "Processed input to iSPN_5 (182), keeping 168 out of 307 inputs (54.72 %)\n",
+      "Processed input to iSPN_15 (183), keeping 35 out of 131 inputs (26.72 %)\n",
+      "Processed input to iSPN_16 (184), keeping 98 out of 174 inputs (56.32 %)\n",
+      "Processed input to iSPN_17 (185), keeping 129 out of 239 inputs (53.97 %)\n",
+      "Processed input to iSPN_25 (186), keeping 230 out of 374 inputs (61.50 %)\n",
+      "Processed input to iSPN_27 (187), keeping 54 out of 147 inputs (36.73 %)\n",
+      "Processed input to dSPN_13 (188), keeping 68 out of 270 inputs (25.19 %)\n",
+      "Processed input to dSPN_28 (189), keeping 195 out of 419 inputs (46.54 %)\n",
+      "Processed input to dSPN_16 (19), keeping 173 out of 392 inputs (44.13 %)\n",
+      "Processed input to iSPN_22 (190), keeping 95 out of 211 inputs (45.02 %)\n",
+      "Processed input to dSPN_21 (191), keeping 266 out of 587 inputs (45.32 %)\n",
+      "Processed input to dSPN_23 (192), keeping 265 out of 480 inputs (55.21 %)\n",
+      "Processed input to iSPN_34 (193), keeping 122 out of 275 inputs (44.36 %)\n",
+      "Processed input to FS_2 (194), keeping 695 out of 725 inputs (95.86 %)\n",
+      "Processed input to iSPN_4 (195), keeping 147 out of 312 inputs (47.12 %)\n",
+      "Processed input to iSPN_26 (196), keeping 54 out of 129 inputs (41.86 %)\n",
+      "Processed input to iSPN_33 (197), keeping 166 out of 283 inputs (58.66 %)\n",
+      "Processed input to dSPN_3 (198), keeping 65 out of 220 inputs (29.55 %)\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Processed input to dSPN_28 (199), keeping 189 out of 410 inputs (46.10 %)\n",
+      "Processed input to iSPN_2 (2), keeping 70 out of 100 inputs (70.00 %)\n",
+      "Processed input to dSPN_26 (20), keeping 89 out of 298 inputs (29.87 %)\n",
+      "Processed input to iSPN_5 (200), keeping 215 out of 362 inputs (59.39 %)\n",
+      "Processed input to iSPN_27 (201), keeping 47 out of 142 inputs (33.10 %)\n",
+      "Processed input to iSPN_30 (202), keeping 63 out of 136 inputs (46.32 %)\n",
+      "Processed input to iSPN_33 (203), keeping 143 out of 258 inputs (55.43 %)\n",
+      "Processed input to dSPN_4 (204), keeping 147 out of 445 inputs (33.03 %)\n",
+      "Processed input to dSPN_15 (205), keeping 29 out of 223 inputs (13.00 %)\n",
+      "Processed input to dSPN_17 (206), keeping 223 out of 475 inputs (46.95 %)\n",
+      "Processed input to dSPN_29 (207), keeping 257 out of 484 inputs (53.10 %)\n",
+      "Processed input to dSPN_19 (208), keeping 45 out of 288 inputs (15.62 %)\n",
+      "Processed input to dSPN_30 (209), keeping 111 out of 303 inputs (36.63 %)\n",
+      "Processed input to iSPN_3 (21), keeping 112 out of 290 inputs (38.62 %)\n",
+      "Processed input to dSPN_35 (210), keeping 380 out of 641 inputs (59.28 %)\n",
+      "Processed input to FS_0 (211), keeping 412 out of 420 inputs (98.10 %)\n",
+      "Processed input to dSPN_6 (212), keeping 218 out of 418 inputs (52.15 %)\n",
+      "Processed input to iSPN_15 (213), keeping 43 out of 156 inputs (27.56 %)\n",
+      "Processed input to dSPN_10 (214), keeping 255 out of 466 inputs (54.72 %)\n",
+      "Processed input to iSPN_1 (215), keeping 50 out of 155 inputs (32.26 %)\n",
+      "Processed input to iSPN_12 (216), keeping 191 out of 306 inputs (62.42 %)\n",
+      "Processed input to iSPN_20 (217), keeping 26 out of 110 inputs (23.64 %)\n",
+      "Processed input to dSPN_8 (218), keeping 143 out of 360 inputs (39.72 %)\n",
+      "Processed input to dSPN_21 (219), keeping 284 out of 576 inputs (49.31 %)\n",
+      "Processed input to iSPN_17 (22), keeping 112 out of 238 inputs (47.06 %)\n",
+      "Processed input to iSPN_6 (220), keeping 155 out of 260 inputs (59.62 %)\n",
+      "Processed input to iSPN_34 (221), keeping 123 out of 280 inputs (43.93 %)\n",
+      "Processed input to dSPN_6 (222), keeping 183 out of 394 inputs (46.45 %)\n",
+      "Processed input to dSPN_13 (223), keeping 77 out of 285 inputs (27.02 %)\n",
+      "Processed input to dSPN_14 (224), keeping 259 out of 469 inputs (55.22 %)\n",
+      "Processed input to iSPN_7 (225), keeping 110 out of 206 inputs (53.40 %)\n",
+      "Processed input to iSPN_21 (226), keeping 208 out of 366 inputs (56.83 %)\n",
+      "Processed input to iSPN_28 (227), keeping 124 out of 216 inputs (57.41 %)\n",
+      "Processed input to dSPN_13 (228), keeping 61 out of 249 inputs (24.50 %)\n",
+      "Processed input to iSPN_17 (229), keeping 138 out of 274 inputs (50.36 %)\n",
+      "Processed input to iSPN_31 (23), keeping 81 out of 183 inputs (44.26 %)\n",
+      "Processed input to iSPN_29 (230), keeping 132 out of 240 inputs (55.00 %)\n",
+      "Processed input to dSPN_25 (231), keeping 336 out of 600 inputs (56.00 %)\n",
+      "Processed input to iSPN_1 (232), keeping 63 out of 155 inputs (40.65 %)\n",
+      "Processed input to iSPN_28 (233), keeping 132 out of 222 inputs (59.46 %)\n",
+      "Processed input to dSPN_15 (234), keeping 25 out of 257 inputs (9.73 %)\n",
+      "Processed input to dSPN_15 (235), keeping 24 out of 249 inputs (9.64 %)\n",
+      "Processed input to iSPN_6 (236), keeping 139 out of 259 inputs (53.67 %)\n",
+      "Processed input to iSPN_24 (237), keeping 85 out of 235 inputs (36.17 %)\n",
+      "Processed input to iSPN_30 (238), keeping 73 out of 172 inputs (42.44 %)\n",
+      "Processed input to dSPN_33 (239), keeping 274 out of 506 inputs (54.15 %)\n",
+      "Processed input to dSPN_3 (24), keeping 83 out of 220 inputs (37.73 %)\n",
+      "Processed input to iSPN_13 (240), keeping 43 out of 119 inputs (36.13 %)\n",
+      "Processed input to iSPN_14 (241), keeping 176 out of 291 inputs (60.48 %)\n",
+      "Processed input to iSPN_35 (242), keeping 279 out of 434 inputs (64.29 %)\n",
+      "Processed input to dSPN_8 (243), keeping 142 out of 344 inputs (41.28 %)\n",
+      "Processed input to dSPN_32 (244), keeping 214 out of 422 inputs (50.71 %)\n",
+      "Processed input to iSPN_9 (245), keeping 85 out of 217 inputs (39.17 %)\n",
+      "Processed input to iSPN_16 (246), keeping 103 out of 182 inputs (56.59 %)\n",
+      "Processed input to iSPN_21 (247), keeping 235 out of 376 inputs (62.50 %)\n",
+      "Processed input to dSPN_29 (248), keeping 237 out of 494 inputs (47.98 %)\n",
+      "Processed input to iSPN_13 (249), keeping 35 out of 127 inputs (27.56 %)\n",
+      "Processed input to dSPN_20 (25), keeping 36 out of 205 inputs (17.56 %)\n",
+      "Processed input to iSPN_14 (250), keeping 193 out of 320 inputs (60.31 %)\n",
+      "Processed input to iSPN_15 (251), keeping 31 out of 161 inputs (19.25 %)\n",
+      "Processed input to iSPN_30 (252), keeping 81 out of 172 inputs (47.09 %)\n",
+      "Processed input to dSPN_1 (253), keeping 70 out of 265 inputs (26.42 %)\n",
+      "Processed input to iSPN_4 (254), keeping 139 out of 308 inputs (45.13 %)\n",
+      "Processed input to iSPN_11 (255), keeping 135 out of 244 inputs (55.33 %)\n",
+      "Processed input to FS_3 (256), keeping 510 out of 525 inputs (97.14 %)\n",
+      "Processed input to iSPN_22 (257), keeping 103 out of 194 inputs (53.09 %)\n",
+      "Processed input to dSPN_12 (258), keeping 288 out of 519 inputs (55.49 %)\n",
+      "Processed input to iSPN_0 (259), keeping 102 out of 150 inputs (68.00 %)\n",
+      "Processed input to dSPN_24 (26), keeping 86 out of 337 inputs (25.52 %)\n",
+      "Processed input to iSPN_10 (260), keeping 155 out of 227 inputs (68.28 %)\n",
+      "Processed input to iSPN_14 (261), keeping 170 out of 287 inputs (59.23 %)\n",
+      "Processed input to dSPN_7 (262), keeping 185 out of 416 inputs (44.47 %)\n",
+      "Processed input to iSPN_6 (263), keeping 176 out of 288 inputs (61.11 %)\n",
+      "Processed input to iSPN_35 (264), keeping 280 out of 419 inputs (66.83 %)\n",
+      "Processed input to dSPN_11 (265), keeping 171 out of 383 inputs (44.65 %)\n",
+      "Processed input to dSPN_25 (266), keeping 354 out of 662 inputs (53.47 %)\n",
+      "Processed input to dSPN_33 (267), keeping 304 out of 526 inputs (57.79 %)\n",
+      "Processed input to iSPN_24 (268), keeping 118 out of 274 inputs (43.07 %)\n",
+      "Processed input to dSPN_8 (269), keeping 136 out of 330 inputs (41.21 %)\n",
+      "Processed input to dSPN_29 (27), keeping 253 out of 467 inputs (54.18 %)\n",
+      "Processed input to dSPN_11 (270), keeping 177 out of 366 inputs (48.36 %)\n",
+      "Processed input to dSPN_22 (271), keeping 118 out of 342 inputs (34.50 %)\n",
+      "Processed input to dSPN_28 (272), keeping 199 out of 439 inputs (45.33 %)\n",
+      "Processed input to dSPN_26 (273), keeping 87 out of 300 inputs (29.00 %)\n",
+      "Processed input to iSPN_7 (274), keeping 97 out of 202 inputs (48.02 %)\n",
+      "Processed input to iSPN_18 (275), keeping 248 out of 411 inputs (60.34 %)\n",
+      "Processed input to dSPN_4 (276), keeping 180 out of 456 inputs (39.47 %)\n",
+      "Processed input to iSPN_26 (277), keeping 54 out of 141 inputs (38.30 %)\n",
+      "Processed input to dSPN_6 (278), keeping 198 out of 408 inputs (48.53 %)\n",
+      "Processed input to iSPN_12 (279), keeping 190 out of 311 inputs (61.09 %)\n",
+      "Processed input to iSPN_19 (28), keeping 73 out of 223 inputs (32.74 %)\n",
+      "Processed input to iSPN_32 (280), keeping 133 out of 217 inputs (61.29 %)\n",
+      "Processed input to iSPN_33 (281), keeping 172 out of 291 inputs (59.11 %)\n",
+      "Processed input to dSPN_10 (282), keeping 267 out of 509 inputs (52.46 %)\n",
+      "Processed input to dSPN_16 (283), keeping 182 out of 401 inputs (45.39 %)\n",
+      "Processed input to iSPN_20 (284), keeping 36 out of 113 inputs (31.86 %)\n",
+      "Processed input to iSPN_23 (285), keeping 208 out of 316 inputs (65.82 %)\n",
+      "Processed input to dSPN_0 (286), keeping 86 out of 135 inputs (63.70 %)\n",
+      "Processed input to dSPN_2 (287), keeping 217 out of 325 inputs (66.77 %)\n",
+      "Processed input to dSPN_13 (288), keeping 76 out of 265 inputs (28.68 %)\n",
+      "Processed input to dSPN_13 (289), keeping 62 out of 270 inputs (22.96 %)\n",
+      "Processed input to iSPN_30 (29), keeping 82 out of 171 inputs (47.95 %)\n",
+      "Processed input to dSPN_30 (290), keeping 106 out of 323 inputs (32.82 %)\n",
+      "Processed input to iSPN_11 (291), keeping 128 out of 234 inputs (54.70 %)\n",
+      "Processed input to dSPN_9 (292), keeping 147 out of 403 inputs (36.48 %)\n",
+      "Processed input to dSPN_21 (293), keeping 294 out of 536 inputs (54.85 %)\n",
+      "Processed input to iSPN_12 (294), keeping 156 out of 257 inputs (60.70 %)\n",
+      "Processed input to iSPN_25 (295), keeping 254 out of 418 inputs (60.77 %)\n",
+      "Processed input to dSPN_16 (296), keeping 179 out of 396 inputs (45.20 %)\n",
+      "Processed input to dSPN_31 (297), keeping 100 out of 326 inputs (30.67 %)\n",
+      "Processed input to iSPN_8 (298), keeping 90 out of 174 inputs (51.72 %)\n",
+      "Processed input to dSPN_17 (299), keeping 202 out of 428 inputs (47.20 %)\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Processed input to iSPN_6 (3), keeping 145 out of 273 inputs (53.11 %)\n",
+      "Processed input to iSPN_5 (30), keeping 179 out of 337 inputs (53.12 %)\n",
+      "Processed input to dSPN_19 (300), keeping 49 out of 293 inputs (16.72 %)\n",
+      "Processed input to dSPN_20 (301), keeping 35 out of 208 inputs (16.83 %)\n",
+      "Processed input to dSPN_32 (302), keeping 229 out of 441 inputs (51.93 %)\n",
+      "Processed input to iSPN_4 (303), keeping 146 out of 318 inputs (45.91 %)\n",
+      "Processed input to iSPN_7 (304), keeping 105 out of 215 inputs (48.84 %)\n",
+      "Processed input to dSPN_8 (305), keeping 155 out of 365 inputs (42.47 %)\n",
+      "Processed input to dSPN_12 (306), keeping 340 out of 575 inputs (59.13 %)\n",
+      "Processed input to dSPN_21 (307), keeping 301 out of 584 inputs (51.54 %)\n",
+      "Processed input to dSPN_34 (308), keeping 127 out of 420 inputs (30.24 %)\n",
+      "Processed input to iSPN_23 (309), keeping 193 out of 313 inputs (61.66 %)\n",
+      "Processed input to iSPN_15 (31), keeping 40 out of 131 inputs (30.53 %)\n",
+      "Processed input to iSPN_27 (310), keeping 64 out of 162 inputs (39.51 %)\n",
+      "Processed input to iSPN_32 (311), keeping 139 out of 229 inputs (60.70 %)\n",
+      "Processed input to iSPN_0 (312), keeping 101 out of 150 inputs (67.33 %)\n",
+      "Processed input to iSPN_32 (313), keeping 130 out of 214 inputs (60.75 %)\n",
+      "Processed input to dSPN_35 (314), keeping 410 out of 683 inputs (60.03 %)\n",
+      "Processed input to iSPN_4 (315), keeping 152 out of 301 inputs (50.50 %)\n",
+      "Processed input to iSPN_7 (316), keeping 109 out of 226 inputs (48.23 %)\n",
+      "Processed input to iSPN_13 (317), keeping 33 out of 100 inputs (33.00 %)\n",
+      "Processed input to dSPN_17 (318), keeping 208 out of 446 inputs (46.64 %)\n",
+      "Processed input to iSPN_6 (319), keeping 165 out of 279 inputs (59.14 %)\n",
+      "Processed input to iSPN_26 (32), keeping 63 out of 156 inputs (40.38 %)\n",
+      "Processed input to iSPN_9 (320), keeping 103 out of 196 inputs (52.55 %)\n",
+      "Processed input to iSPN_31 (321), keeping 68 out of 180 inputs (37.78 %)\n",
+      "Processed input to dSPN_2 (322), keeping 209 out of 325 inputs (64.31 %)\n",
+      "Processed input to dSPN_11 (323), keeping 159 out of 364 inputs (43.68 %)\n",
+      "Processed input to dSPN_24 (324), keeping 76 out of 317 inputs (23.97 %)\n",
+      "Processed input to iSPN_19 (325), keeping 73 out of 232 inputs (31.47 %)\n",
+      "Processed input to iSPN_29 (326), keeping 158 out of 273 inputs (57.88 %)\n",
+      "Processed input to iSPN_35 (327), keeping 293 out of 460 inputs (63.70 %)\n",
+      "Processed input to dSPN_35 (328), keeping 415 out of 692 inputs (59.97 %)\n",
+      "Processed input to iSPN_7 (329), keeping 122 out of 258 inputs (47.29 %)\n",
+      "Processed input to iSPN_33 (33), keeping 161 out of 275 inputs (58.55 %)\n",
+      "Processed input to dSPN_24 (330), keeping 114 out of 397 inputs (28.72 %)\n",
+      "Processed input to dSPN_26 (331), keeping 91 out of 293 inputs (31.06 %)\n",
+      "Processed input to iSPN_2 (332), keeping 67 out of 100 inputs (67.00 %)\n",
+      "Processed input to iSPN_14 (333), keeping 183 out of 290 inputs (63.10 %)\n",
+      "Processed input to iSPN_21 (334), keeping 254 out of 420 inputs (60.48 %)\n",
+      "Processed input to dSPN_17 (335), keeping 223 out of 452 inputs (49.34 %)\n",
+      "Processed input to iSPN_7 (336), keeping 112 out of 226 inputs (49.56 %)\n",
+      "Processed input to iSPN_12 (337), keeping 184 out of 306 inputs (60.13 %)\n",
+      "Processed input to iSPN_29 (338), keeping 155 out of 250 inputs (62.00 %)\n",
+      "Processed input to dSPN_6 (339), keeping 227 out of 419 inputs (54.18 %)\n",
+      "Processed input to dSPN_19 (34), keeping 57 out of 304 inputs (18.75 %)\n",
+      "Processed input to dSPN_14 (340), keeping 242 out of 446 inputs (54.26 %)\n",
+      "Processed input to dSPN_30 (341), keeping 111 out of 309 inputs (35.92 %)\n",
+      "Processed input to iSPN_22 (342), keeping 105 out of 218 inputs (48.17 %)\n",
+      "Processed input to iSPN_25 (343), keeping 267 out of 425 inputs (62.82 %)\n",
+      "Processed input to iSPN_25 (344), keeping 276 out of 429 inputs (64.34 %)\n",
+      "Processed input to dSPN_16 (345), keeping 175 out of 396 inputs (44.19 %)\n",
+      "Processed input to iSPN_13 (346), keeping 47 out of 130 inputs (36.15 %)\n",
+      "Processed input to iSPN_16 (347), keeping 96 out of 176 inputs (54.55 %)\n",
+      "Processed input to iSPN_9 (348), keeping 103 out of 227 inputs (45.37 %)\n",
+      "Processed input to iSPN_26 (349), keeping 47 out of 131 inputs (35.88 %)\n",
+      "Processed input to iSPN_10 (35), keeping 135 out of 202 inputs (66.83 %)\n",
+      "Processed input to dSPN_9 (350), keeping 128 out of 370 inputs (34.59 %)\n",
+      "Processed input to dSPN_22 (351), keeping 127 out of 335 inputs (37.91 %)\n",
+      "Processed input to iSPN_11 (352), keeping 133 out of 237 inputs (56.12 %)\n",
+      "Processed input to iSPN_32 (353), keeping 130 out of 206 inputs (63.11 %)\n",
+      "Processed input to dSPN_21 (354), keeping 320 out of 627 inputs (51.04 %)\n",
+      "Processed input to dSPN_23 (355), keeping 275 out of 471 inputs (58.39 %)\n",
+      "Processed input to dSPN_31 (356), keeping 94 out of 345 inputs (27.25 %)\n",
+      "Processed input to dSPN_32 (357), keeping 235 out of 438 inputs (53.65 %)\n",
+      "Processed input to iSPN_31 (358), keeping 88 out of 223 inputs (39.46 %)\n",
+      "Processed input to dSPN_1 (359), keeping 72 out of 265 inputs (27.17 %)\n",
+      "Processed input to iSPN_11 (36), keeping 136 out of 251 inputs (54.18 %)\n",
+      "Processed input to dSPN_5 (360), keeping 208 out of 474 inputs (43.88 %)\n",
+      "Processed input to iSPN_1 (361), keeping 58 out of 155 inputs (37.42 %)\n",
+      "Processed input to iSPN_26 (362), keeping 57 out of 142 inputs (40.14 %)\n",
+      "Processed input to iSPN_28 (363), keeping 116 out of 202 inputs (57.43 %)\n",
+      "Processed input to dSPN_5 (364), keeping 224 out of 481 inputs (46.57 %)\n",
+      "Processed input to dSPN_5 (365), keeping 232 out of 491 inputs (47.25 %)\n",
+      "Processed input to dSPN_24 (366), keeping 94 out of 353 inputs (26.63 %)\n",
+      "Processed input to dSPN_25 (367), keeping 349 out of 628 inputs (55.57 %)\n",
+      "Processed input to iSPN_26 (368), keeping 60 out of 139 inputs (43.17 %)\n",
+      "Processed input to iSPN_32 (369), keeping 136 out of 199 inputs (68.34 %)\n",
+      "Processed input to iSPN_18 (37), keeping 202 out of 373 inputs (54.16 %)\n",
+      "Processed input to iSPN_34 (370), keeping 113 out of 294 inputs (38.44 %)\n",
+      "Processed input to dSPN_4 (371), keeping 158 out of 434 inputs (36.41 %)\n",
+      "Processed input to dSPN_18 (372), keeping 257 out of 538 inputs (47.77 %)\n",
+      "Processed input to iSPN_27 (373), keeping 48 out of 160 inputs (30.00 %)\n",
+      "Processed input to dSPN_7 (374), keeping 203 out of 418 inputs (48.56 %)\n",
+      "Processed input to dSPN_9 (375), keeping 141 out of 377 inputs (37.40 %)\n",
+      "Processed input to dSPN_10 (376), keeping 247 out of 478 inputs (51.67 %)\n",
+      "Processed input to dSPN_25 (377), keeping 329 out of 601 inputs (54.74 %)\n",
+      "Processed input to iSPN_14 (378), keeping 174 out of 305 inputs (57.05 %)\n",
+      "Processed input to dSPN_4 (379), keeping 159 out of 440 inputs (36.14 %)\n",
+      "Processed input to iSPN_24 (38), keeping 101 out of 253 inputs (39.92 %)\n",
+      "Processed input to iSPN_10 (380), keeping 143 out of 233 inputs (61.37 %)\n",
+      "Processed input to iSPN_24 (381), keeping 101 out of 252 inputs (40.08 %)\n",
+      "Processed input to dSPN_31 (382), keeping 98 out of 330 inputs (29.70 %)\n",
+      "Processed input to dSPN_0 (383), keeping 87 out of 135 inputs (64.44 %)\n",
+      "Processed input to dSPN_16 (384), keeping 174 out of 376 inputs (46.28 %)\n",
+      "Processed input to iSPN_20 (385), keeping 38 out of 115 inputs (33.04 %)\n",
+      "Processed input to iSPN_21 (386), keeping 206 out of 368 inputs (55.98 %)\n",
+      "Processed input to dSPN_3 (387), keeping 73 out of 220 inputs (33.18 %)\n",
+      "Processed input to dSPN_8 (388), keeping 149 out of 354 inputs (42.09 %)\n",
+      "Processed input to iSPN_8 (389), keeping 82 out of 162 inputs (50.62 %)\n",
+      "Processed input to iSPN_29 (39), keeping 150 out of 267 inputs (56.18 %)\n",
+      "Processed input to iSPN_12 (390), keeping 178 out of 291 inputs (61.17 %)\n",
+      "Processed input to iSPN_18 (391), keeping 219 out of 361 inputs (60.66 %)\n",
+      "Processed input to iSPN_19 (392), keeping 70 out of 247 inputs (28.34 %)\n",
+      "Processed input to iSPN_23 (393), keeping 172 out of 263 inputs (65.40 %)\n",
+      "Processed input to dSPN_0 (394), keeping 85 out of 135 inputs (62.96 %)\n",
+      "Processed input to dSPN_12 (395), keeping 314 out of 560 inputs (56.07 %)\n",
+      "Processed input to dSPN_14 (396), keeping 239 out of 436 inputs (54.82 %)\n",
+      "Processed input to dSPN_15 (397), keeping 27 out of 237 inputs (11.39 %)\n",
+      "Processed input to dSPN_28 (398), keeping 202 out of 418 inputs (48.33 %)\n",
+      "Processed input to dSPN_5 (399), keeping 225 out of 481 inputs (46.78 %)\n",
+      "Processed input to iSPN_15 (4), keeping 34 out of 136 inputs (25.00 %)\n",
+      "Processed input to dSPN_0 (40), keeping 88 out of 135 inputs (65.19 %)\n",
+      "Processed input to dSPN_11 (400), keeping 173 out of 386 inputs (44.82 %)\n",
+      "Processed input to dSPN_29 (401), keeping 282 out of 517 inputs (54.55 %)\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Processed input to iSPN_5 (402), keeping 204 out of 352 inputs (57.95 %)\n",
+      "Processed input to iSPN_16 (403), keeping 103 out of 188 inputs (54.79 %)\n",
+      "Processed input to iSPN_0 (41), keeping 91 out of 150 inputs (60.67 %)\n",
+      "Processed input to iSPN_19 (42), keeping 69 out of 222 inputs (31.08 %)\n",
+      "Processed input to dSPN_28 (43), keeping 207 out of 407 inputs (50.86 %)\n",
+      "Processed input to iSPN_17 (44), keeping 120 out of 243 inputs (49.38 %)\n",
+      "Processed input to iSPN_35 (45), keeping 308 out of 464 inputs (66.38 %)\n",
+      "Processed input to dSPN_19 (46), keeping 51 out of 307 inputs (16.61 %)\n",
+      "Processed input to dSPN_34 (47), keeping 133 out of 381 inputs (34.91 %)\n",
+      "Processed input to iSPN_2 (48), keeping 72 out of 100 inputs (72.00 %)\n",
+      "Processed input to iSPN_8 (49), keeping 103 out of 198 inputs (52.02 %)\n",
+      "Processed input to iSPN_34 (5), keeping 139 out of 275 inputs (50.55 %)\n",
+      "Processed input to iSPN_10 (50), keeping 137 out of 229 inputs (59.83 %)\n",
+      "Processed input to iSPN_30 (51), keeping 79 out of 166 inputs (47.59 %)\n",
+      "Processed input to dSPN_1 (52), keeping 64 out of 265 inputs (24.15 %)\n",
+      "Processed input to dSPN_13 (53), keeping 64 out of 265 inputs (24.15 %)\n",
+      "Processed input to dSPN_27 (54), keeping 59 out of 276 inputs (21.38 %)\n",
+      "Processed input to dSPN_25 (55), keeping 328 out of 616 inputs (53.25 %)\n",
+      "Processed input to dSPN_34 (56), keeping 120 out of 390 inputs (30.77 %)\n",
+      "Processed input to dSPN_27 (57), keeping 60 out of 267 inputs (22.47 %)\n",
+      "Processed input to dSPN_31 (58), keeping 82 out of 316 inputs (25.95 %)\n",
+      "Processed input to iSPN_13 (59), keeping 39 out of 103 inputs (37.86 %)\n",
+      "Processed input to dSPN_15 (6), keeping 33 out of 250 inputs (13.20 %)\n",
+      "Processed input to iSPN_23 (60), keeping 201 out of 327 inputs (61.47 %)\n",
+      "Processed input to iSPN_35 (61), keeping 286 out of 449 inputs (63.70 %)\n",
+      "Processed input to dSPN_26 (62), keeping 82 out of 289 inputs (28.37 %)\n",
+      "Processed input to iSPN_3 (63), keeping 115 out of 290 inputs (39.66 %)\n",
+      "Processed input to iSPN_5 (64), keeping 208 out of 356 inputs (58.43 %)\n",
+      "Processed input to dSPN_21 (65), keeping 328 out of 618 inputs (53.07 %)\n",
+      "Processed input to dSPN_23 (66), keeping 264 out of 494 inputs (53.44 %)\n",
+      "Processed input to dSPN_27 (67), keeping 59 out of 297 inputs (19.87 %)\n",
+      "Processed input to iSPN_1 (68), keeping 54 out of 155 inputs (34.84 %)\n",
+      "Processed input to iSPN_4 (69), keeping 151 out of 313 inputs (48.24 %)\n",
+      "Processed input to dSPN_24 (7), keeping 84 out of 355 inputs (23.66 %)\n",
+      "Processed input to dSPN_22 (70), keeping 160 out of 361 inputs (44.32 %)\n",
+      "Processed input to dSPN_30 (71), keeping 95 out of 316 inputs (30.06 %)\n",
+      "Processed input to dSPN_18 (72), keeping 273 out of 542 inputs (50.37 %)\n",
+      "Processed input to dSPN_30 (73), keeping 117 out of 317 inputs (36.91 %)\n",
+      "Processed input to iSPN_16 (74), keeping 91 out of 171 inputs (53.22 %)\n",
+      "Processed input to iSPN_22 (75), keeping 118 out of 239 inputs (49.37 %)\n",
+      "Processed input to dSPN_5 (76), keeping 197 out of 438 inputs (44.98 %)\n",
+      "Processed input to dSPN_6 (77), keeping 221 out of 416 inputs (53.12 %)\n",
+      "Processed input to iSPN_15 (78), keeping 36 out of 148 inputs (24.32 %)\n",
+      "Processed input to iSPN_16 (79), keeping 109 out of 178 inputs (61.24 %)\n",
+      "Processed input to iSPN_3 (8), keeping 138 out of 290 inputs (47.59 %)\n",
+      "Processed input to iSPN_9 (80), keeping 87 out of 204 inputs (42.65 %)\n",
+      "Processed input to iSPN_20 (81), keeping 36 out of 109 inputs (33.03 %)\n",
+      "Processed input to iSPN_28 (82), keeping 111 out of 201 inputs (55.22 %)\n",
+      "Processed input to iSPN_35 (83), keeping 288 out of 428 inputs (67.29 %)\n",
+      "Processed input to dSPN_11 (84), keeping 182 out of 375 inputs (48.53 %)\n",
+      "Processed input to dSPN_33 (85), keeping 308 out of 525 inputs (58.67 %)\n",
+      "Processed input to iSPN_3 (86), keeping 121 out of 290 inputs (41.72 %)\n",
+      "Processed input to iSPN_30 (87), keeping 70 out of 135 inputs (51.85 %)\n",
+      "Processed input to dSPN_1 (88), keeping 67 out of 255 inputs (26.27 %)\n",
+      "Processed input to dSPN_5 (89), keeping 229 out of 477 inputs (48.01 %)\n",
+      "Processed input to iSPN_17 (9), keeping 135 out of 258 inputs (52.33 %)\n",
+      "Processed input to dSPN_10 (90), keeping 262 out of 506 inputs (51.78 %)\n",
+      "Processed input to dSPN_22 (91), keeping 130 out of 331 inputs (39.27 %)\n",
+      "Processed input to dSPN_29 (92), keeping 259 out of 484 inputs (53.51 %)\n",
+      "Processed input to iSPN_2 (93), keeping 71 out of 100 inputs (71.00 %)\n",
+      "Processed input to iSPN_5 (94), keeping 191 out of 344 inputs (55.52 %)\n",
+      "Processed input to iSPN_29 (95), keeping 163 out of 313 inputs (52.08 %)\n",
+      "Processed input to dSPN_1 (96), keeping 79 out of 265 inputs (29.81 %)\n",
+      "Processed input to dSPN_2 (97), keeping 220 out of 325 inputs (67.69 %)\n",
+      "Processed input to dSPN_9 (98), keeping 124 out of 364 inputs (34.07 %)\n",
+      "Processed input to iSPN_14 (99), keeping 170 out of 297 inputs (57.24 %)\n"
+     ]
+    }
+   ],
+   "source": [
+    "from snudda.utils.swap_to_degenerated_morphologies import SwapToDegenerateMorphologies\n",
+    "\n",
+    "swap = SwapToDegenerateMorphologies(original_network_file=original_network_file,\n",
+    "                                    new_network_file=new_network_file,\n",
+    "                                    original_snudda_data_dir=SNUDDA_DATA_WT,\n",
+    "                                    new_snudda_data_dir=SNUDDA_DATA_PD2,\n",
+    "                                    original_input_file=original_input_file,\n",
+    "                                    new_input_file=new_input_file)\n",
+    "swap.write_new_network_file()\n",
+    "swap.write_new_input_file()\n",
+    "swap.close()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "id": "bce789ec",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Loading 404 neurons with 73718 synapses and 20 gap junctions\n",
+      "Loading 404 neurons with 37191 synapses and 19 gap junctions\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd0/neurons/striatum/dspn/28/parameters.json\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "/* Put everything inside the global mpl namespace */\n",
+       "/* global mpl */\n",
+       "window.mpl = {};\n",
+       "\n",
+       "mpl.get_websocket_type = function () {\n",
+       "    if (typeof WebSocket !== 'undefined') {\n",
+       "        return WebSocket;\n",
+       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
+       "        return MozWebSocket;\n",
+       "    } else {\n",
+       "        alert(\n",
+       "            'Your browser does not have WebSocket support. ' +\n",
+       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+       "                'Firefox 4 and 5 are also supported but you ' +\n",
+       "                'have to enable WebSockets in about:config.'\n",
+       "        );\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
+       "    this.id = figure_id;\n",
+       "\n",
+       "    this.ws = websocket;\n",
+       "\n",
+       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
+       "\n",
+       "    if (!this.supports_binary) {\n",
+       "        var warnings = document.getElementById('mpl-warnings');\n",
+       "        if (warnings) {\n",
+       "            warnings.style.display = 'block';\n",
+       "            warnings.textContent =\n",
+       "                'This browser does not support binary websocket messages. ' +\n",
+       "                'Performance may be slow.';\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.imageObj = new Image();\n",
+       "\n",
+       "    this.context = undefined;\n",
+       "    this.message = undefined;\n",
+       "    this.canvas = undefined;\n",
+       "    this.rubberband_canvas = undefined;\n",
+       "    this.rubberband_context = undefined;\n",
+       "    this.format_dropdown = undefined;\n",
+       "\n",
+       "    this.image_mode = 'full';\n",
+       "\n",
+       "    this.root = document.createElement('div');\n",
+       "    this.root.setAttribute('style', 'display: inline-block');\n",
+       "    this._root_extra_style(this.root);\n",
+       "\n",
+       "    parent_element.appendChild(this.root);\n",
+       "\n",
+       "    this._init_header(this);\n",
+       "    this._init_canvas(this);\n",
+       "    this._init_toolbar(this);\n",
+       "\n",
+       "    var fig = this;\n",
+       "\n",
+       "    this.waiting = false;\n",
+       "\n",
+       "    this.ws.onopen = function () {\n",
+       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
+       "        fig.send_message('send_image_mode', {});\n",
+       "        if (fig.ratio !== 1) {\n",
+       "            fig.send_message('set_device_pixel_ratio', {\n",
+       "                device_pixel_ratio: fig.ratio,\n",
+       "            });\n",
+       "        }\n",
+       "        fig.send_message('refresh', {});\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onload = function () {\n",
+       "        if (fig.image_mode === 'full') {\n",
+       "            // Full images could contain transparency (where diff images\n",
+       "            // almost always do), so we need to clear the canvas so that\n",
+       "            // there is no ghosting.\n",
+       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+       "        }\n",
+       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
+       "    };\n",
+       "\n",
+       "    this.imageObj.onunload = function () {\n",
+       "        fig.ws.close();\n",
+       "    };\n",
+       "\n",
+       "    this.ws.onmessage = this._make_on_message_function(this);\n",
+       "\n",
+       "    this.ondownload = ondownload;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_header = function () {\n",
+       "    var titlebar = document.createElement('div');\n",
+       "    titlebar.classList =\n",
+       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
+       "    var titletext = document.createElement('div');\n",
+       "    titletext.classList = 'ui-dialog-title';\n",
+       "    titletext.setAttribute(\n",
+       "        'style',\n",
+       "        'width: 100%; text-align: center; padding: 3px;'\n",
+       "    );\n",
+       "    titlebar.appendChild(titletext);\n",
+       "    this.root.appendChild(titlebar);\n",
+       "    this.header = titletext;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
+       "\n",
+       "mpl.figure.prototype._init_canvas = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
+       "    canvas_div.setAttribute(\n",
+       "        'style',\n",
+       "        'border: 1px solid #ddd;' +\n",
+       "            'box-sizing: content-box;' +\n",
+       "            'clear: both;' +\n",
+       "            'min-height: 1px;' +\n",
+       "            'min-width: 1px;' +\n",
+       "            'outline: 0;' +\n",
+       "            'overflow: hidden;' +\n",
+       "            'position: relative;' +\n",
+       "            'resize: both;'\n",
+       "    );\n",
+       "\n",
+       "    function on_keyboard_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.key_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keydown',\n",
+       "        on_keyboard_event_closure('key_press')\n",
+       "    );\n",
+       "    canvas_div.addEventListener(\n",
+       "        'keyup',\n",
+       "        on_keyboard_event_closure('key_release')\n",
+       "    );\n",
+       "\n",
+       "    this._canvas_extra_style(canvas_div);\n",
+       "    this.root.appendChild(canvas_div);\n",
+       "\n",
+       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
+       "    canvas.classList.add('mpl-canvas');\n",
+       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
+       "\n",
+       "    this.context = canvas.getContext('2d');\n",
+       "\n",
+       "    var backingStore =\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        this.context.webkitBackingStorePixelRatio ||\n",
+       "        this.context.mozBackingStorePixelRatio ||\n",
+       "        this.context.msBackingStorePixelRatio ||\n",
+       "        this.context.oBackingStorePixelRatio ||\n",
+       "        this.context.backingStorePixelRatio ||\n",
+       "        1;\n",
+       "\n",
+       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+       "\n",
+       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
+       "        'canvas'\n",
+       "    ));\n",
+       "    rubberband_canvas.setAttribute(\n",
+       "        'style',\n",
+       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
+       "    );\n",
+       "\n",
+       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
+       "    if (this.ResizeObserver === undefined) {\n",
+       "        if (window.ResizeObserver !== undefined) {\n",
+       "            this.ResizeObserver = window.ResizeObserver;\n",
+       "        } else {\n",
+       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
+       "            this.ResizeObserver = obs.ResizeObserver;\n",
+       "        }\n",
+       "    }\n",
+       "\n",
+       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
+       "        var nentries = entries.length;\n",
+       "        for (var i = 0; i < nentries; i++) {\n",
+       "            var entry = entries[i];\n",
+       "            var width, height;\n",
+       "            if (entry.contentBoxSize) {\n",
+       "                if (entry.contentBoxSize instanceof Array) {\n",
+       "                    // Chrome 84 implements new version of spec.\n",
+       "                    width = entry.contentBoxSize[0].inlineSize;\n",
+       "                    height = entry.contentBoxSize[0].blockSize;\n",
+       "                } else {\n",
+       "                    // Firefox implements old version of spec.\n",
+       "                    width = entry.contentBoxSize.inlineSize;\n",
+       "                    height = entry.contentBoxSize.blockSize;\n",
+       "                }\n",
+       "            } else {\n",
+       "                // Chrome <84 implements even older version of spec.\n",
+       "                width = entry.contentRect.width;\n",
+       "                height = entry.contentRect.height;\n",
+       "            }\n",
+       "\n",
+       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
+       "            // the canvas container.\n",
+       "            if (entry.devicePixelContentBoxSize) {\n",
+       "                // Chrome 84 implements new version of spec.\n",
+       "                canvas.setAttribute(\n",
+       "                    'width',\n",
+       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
+       "                );\n",
+       "                canvas.setAttribute(\n",
+       "                    'height',\n",
+       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
+       "                );\n",
+       "            } else {\n",
+       "                canvas.setAttribute('width', width * fig.ratio);\n",
+       "                canvas.setAttribute('height', height * fig.ratio);\n",
+       "            }\n",
+       "            canvas.setAttribute(\n",
+       "                'style',\n",
+       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
+       "            );\n",
+       "\n",
+       "            rubberband_canvas.setAttribute('width', width);\n",
+       "            rubberband_canvas.setAttribute('height', height);\n",
+       "\n",
+       "            // And update the size in Python. We ignore the initial 0/0 size\n",
+       "            // that occurs as the element is placed into the DOM, which should\n",
+       "            // otherwise not happen due to the minimum size styling.\n",
+       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
+       "                fig.request_resize(width, height);\n",
+       "            }\n",
+       "        }\n",
+       "    });\n",
+       "    this.resizeObserverInstance.observe(canvas_div);\n",
+       "\n",
+       "    function on_mouse_event_closure(name) {\n",
+       "        return function (event) {\n",
+       "            return fig.mouse_event(event, name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousedown',\n",
+       "        on_mouse_event_closure('button_press')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseup',\n",
+       "        on_mouse_event_closure('button_release')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'dblclick',\n",
+       "        on_mouse_event_closure('dblclick')\n",
+       "    );\n",
+       "    // Throttle sequential mouse events to 1 every 20ms.\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mousemove',\n",
+       "        on_mouse_event_closure('motion_notify')\n",
+       "    );\n",
+       "\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseenter',\n",
+       "        on_mouse_event_closure('figure_enter')\n",
+       "    );\n",
+       "    rubberband_canvas.addEventListener(\n",
+       "        'mouseleave',\n",
+       "        on_mouse_event_closure('figure_leave')\n",
+       "    );\n",
+       "\n",
+       "    canvas_div.addEventListener('wheel', function (event) {\n",
+       "        if (event.deltaY < 0) {\n",
+       "            event.step = 1;\n",
+       "        } else {\n",
+       "            event.step = -1;\n",
+       "        }\n",
+       "        on_mouse_event_closure('scroll')(event);\n",
+       "    });\n",
+       "\n",
+       "    canvas_div.appendChild(canvas);\n",
+       "    canvas_div.appendChild(rubberband_canvas);\n",
+       "\n",
+       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
+       "    this.rubberband_context.strokeStyle = '#000000';\n",
+       "\n",
+       "    this._resize_canvas = function (width, height, forward) {\n",
+       "        if (forward) {\n",
+       "            canvas_div.style.width = width + 'px';\n",
+       "            canvas_div.style.height = height + 'px';\n",
+       "        }\n",
+       "    };\n",
+       "\n",
+       "    // Disable right mouse context menu.\n",
+       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
+       "        event.preventDefault();\n",
+       "        return false;\n",
+       "    });\n",
+       "\n",
+       "    function set_focus() {\n",
+       "        canvas.focus();\n",
+       "        canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    window.setTimeout(set_focus, 100);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'mpl-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'mpl-button-group';\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'mpl-button-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
+       "        button.classList = 'mpl-widget';\n",
+       "        button.setAttribute('role', 'button');\n",
+       "        button.setAttribute('aria-disabled', 'false');\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "\n",
+       "        var icon_img = document.createElement('img');\n",
+       "        icon_img.src = '_images/' + image + '.png';\n",
+       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
+       "        icon_img.alt = tooltip;\n",
+       "        button.appendChild(icon_img);\n",
+       "\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    var fmt_picker = document.createElement('select');\n",
+       "    fmt_picker.classList = 'mpl-widget';\n",
+       "    toolbar.appendChild(fmt_picker);\n",
+       "    this.format_dropdown = fmt_picker;\n",
+       "\n",
+       "    for (var ind in mpl.extensions) {\n",
+       "        var fmt = mpl.extensions[ind];\n",
+       "        var option = document.createElement('option');\n",
+       "        option.selected = fmt === mpl.default_extension;\n",
+       "        option.innerHTML = fmt;\n",
+       "        fmt_picker.appendChild(option);\n",
+       "    }\n",
+       "\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
+       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+       "    // which will in turn request a refresh of the image.\n",
+       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_message = function (type, properties) {\n",
+       "    properties['type'] = type;\n",
+       "    properties['figure_id'] = this.id;\n",
+       "    this.ws.send(JSON.stringify(properties));\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.send_draw_message = function () {\n",
+       "    if (!this.waiting) {\n",
+       "        this.waiting = true;\n",
+       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    var format_dropdown = fig.format_dropdown;\n",
+       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+       "    fig.ondownload(fig, format);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
+       "    var size = msg['size'];\n",
+       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
+       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
+       "        fig.send_message('refresh', {});\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
+       "    var x0 = msg['x0'] / fig.ratio;\n",
+       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
+       "    var x1 = msg['x1'] / fig.ratio;\n",
+       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
+       "    x0 = Math.floor(x0) + 0.5;\n",
+       "    y0 = Math.floor(y0) + 0.5;\n",
+       "    x1 = Math.floor(x1) + 0.5;\n",
+       "    y1 = Math.floor(y1) + 0.5;\n",
+       "    var min_x = Math.min(x0, x1);\n",
+       "    var min_y = Math.min(y0, y1);\n",
+       "    var width = Math.abs(x1 - x0);\n",
+       "    var height = Math.abs(y1 - y0);\n",
+       "\n",
+       "    fig.rubberband_context.clearRect(\n",
+       "        0,\n",
+       "        0,\n",
+       "        fig.canvas.width / fig.ratio,\n",
+       "        fig.canvas.height / fig.ratio\n",
+       "    );\n",
+       "\n",
+       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
+       "    // Updates the figure title.\n",
+       "    fig.header.textContent = msg['label'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
+       "    fig.rubberband_canvas.style.cursor = msg['cursor'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
+       "    fig.message.textContent = msg['message'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
+       "    // Request the server to send over a new figure.\n",
+       "    fig.send_draw_message();\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
+       "    fig.image_mode = msg['mode'];\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
+       "    for (var key in msg) {\n",
+       "        if (!(key in fig.buttons)) {\n",
+       "            continue;\n",
+       "        }\n",
+       "        fig.buttons[key].disabled = !msg[key];\n",
+       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
+       "    if (msg['mode'] === 'PAN') {\n",
+       "        fig.buttons['Pan'].classList.add('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    } else if (msg['mode'] === 'ZOOM') {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.add('active');\n",
+       "    } else {\n",
+       "        fig.buttons['Pan'].classList.remove('active');\n",
+       "        fig.buttons['Zoom'].classList.remove('active');\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Called whenever the canvas gets updated.\n",
+       "    this.send_message('ack', {});\n",
+       "};\n",
+       "\n",
+       "// A function to construct a web socket function for onmessage handling.\n",
+       "// Called in the figure constructor.\n",
+       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
+       "    return function socket_on_message(evt) {\n",
+       "        if (evt.data instanceof Blob) {\n",
+       "            var img = evt.data;\n",
+       "            if (img.type !== 'image/png') {\n",
+       "                /* FIXME: We get \"Resource interpreted as Image but\n",
+       "                 * transferred with MIME type text/plain:\" errors on\n",
+       "                 * Chrome.  But how to set the MIME type?  It doesn't seem\n",
+       "                 * to be part of the websocket stream */\n",
+       "                img.type = 'image/png';\n",
+       "            }\n",
+       "\n",
+       "            /* Free the memory for the previous frames */\n",
+       "            if (fig.imageObj.src) {\n",
+       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
+       "                    fig.imageObj.src\n",
+       "                );\n",
+       "            }\n",
+       "\n",
+       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+       "                img\n",
+       "            );\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        } else if (\n",
+       "            typeof evt.data === 'string' &&\n",
+       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
+       "        ) {\n",
+       "            fig.imageObj.src = evt.data;\n",
+       "            fig.updated_canvas_event();\n",
+       "            fig.waiting = false;\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        var msg = JSON.parse(evt.data);\n",
+       "        var msg_type = msg['type'];\n",
+       "\n",
+       "        // Call the  \"handle_{type}\" callback, which takes\n",
+       "        // the figure and JSON message as its only arguments.\n",
+       "        try {\n",
+       "            var callback = fig['handle_' + msg_type];\n",
+       "        } catch (e) {\n",
+       "            console.log(\n",
+       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
+       "                msg\n",
+       "            );\n",
+       "            return;\n",
+       "        }\n",
+       "\n",
+       "        if (callback) {\n",
+       "            try {\n",
+       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+       "                callback(fig, msg);\n",
+       "            } catch (e) {\n",
+       "                console.log(\n",
+       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
+       "                    e,\n",
+       "                    e.stack,\n",
+       "                    msg\n",
+       "                );\n",
+       "            }\n",
+       "        }\n",
+       "    };\n",
+       "};\n",
+       "\n",
+       "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+       "mpl.findpos = function (e) {\n",
+       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+       "    var targ;\n",
+       "    if (!e) {\n",
+       "        e = window.event;\n",
+       "    }\n",
+       "    if (e.target) {\n",
+       "        targ = e.target;\n",
+       "    } else if (e.srcElement) {\n",
+       "        targ = e.srcElement;\n",
+       "    }\n",
+       "    if (targ.nodeType === 3) {\n",
+       "        // defeat Safari bug\n",
+       "        targ = targ.parentNode;\n",
+       "    }\n",
+       "\n",
+       "    // pageX,Y are the mouse positions relative to the document\n",
+       "    var boundingRect = targ.getBoundingClientRect();\n",
+       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
+       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
+       "\n",
+       "    return { x: x, y: y };\n",
+       "};\n",
+       "\n",
+       "/*\n",
+       " * return a copy of an object with only non-object keys\n",
+       " * we need this to avoid circular references\n",
+       " * https://stackoverflow.com/a/24161582/3208463\n",
+       " */\n",
+       "function simpleKeys(original) {\n",
+       "    return Object.keys(original).reduce(function (obj, key) {\n",
+       "        if (typeof original[key] !== 'object') {\n",
+       "            obj[key] = original[key];\n",
+       "        }\n",
+       "        return obj;\n",
+       "    }, {});\n",
+       "}\n",
+       "\n",
+       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
+       "    var canvas_pos = mpl.findpos(event);\n",
+       "\n",
+       "    if (name === 'button_press') {\n",
+       "        this.canvas.focus();\n",
+       "        this.canvas_div.focus();\n",
+       "    }\n",
+       "\n",
+       "    var x = canvas_pos.x * this.ratio;\n",
+       "    var y = canvas_pos.y * this.ratio;\n",
+       "\n",
+       "    this.send_message(name, {\n",
+       "        x: x,\n",
+       "        y: y,\n",
+       "        button: event.button,\n",
+       "        step: event.step,\n",
+       "        guiEvent: simpleKeys(event),\n",
+       "    });\n",
+       "\n",
+       "    /* This prevents the web browser from automatically changing to\n",
+       "     * the text insertion cursor when the button is pressed.  We want\n",
+       "     * to control all of the cursor setting manually through the\n",
+       "     * 'cursor' event from matplotlib */\n",
+       "    event.preventDefault();\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
+       "    // Handle any extra behaviour associated with a key event\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.key_event = function (event, name) {\n",
+       "    // Prevent repeat events\n",
+       "    if (name === 'key_press') {\n",
+       "        if (event.key === this._key) {\n",
+       "            return;\n",
+       "        } else {\n",
+       "            this._key = event.key;\n",
+       "        }\n",
+       "    }\n",
+       "    if (name === 'key_release') {\n",
+       "        this._key = null;\n",
+       "    }\n",
+       "\n",
+       "    var value = '';\n",
+       "    if (event.ctrlKey && event.key !== 'Control') {\n",
+       "        value += 'ctrl+';\n",
+       "    }\n",
+       "    else if (event.altKey && event.key !== 'Alt') {\n",
+       "        value += 'alt+';\n",
+       "    }\n",
+       "    else if (event.shiftKey && event.key !== 'Shift') {\n",
+       "        value += 'shift+';\n",
+       "    }\n",
+       "\n",
+       "    value += 'k' + event.key;\n",
+       "\n",
+       "    this._key_event_extra(event, name);\n",
+       "\n",
+       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
+       "    return false;\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
+       "    if (name === 'download') {\n",
+       "        this.handle_save(this, null);\n",
+       "    } else {\n",
+       "        this.send_message('toolbar_button', { name: name });\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
+       "    this.message.textContent = tooltip;\n",
+       "};\n",
+       "\n",
+       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
+       "// prettier-ignore\n",
+       "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
+       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
+       "\n",
+       "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+       "\n",
+       "mpl.default_extension = \"png\";/* global mpl */\n",
+       "\n",
+       "var comm_websocket_adapter = function (comm) {\n",
+       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
+       "    // object with the appropriate methods. Currently this is a non binary\n",
+       "    // socket, so there is still some room for performance tuning.\n",
+       "    var ws = {};\n",
+       "\n",
+       "    ws.binaryType = comm.kernel.ws.binaryType;\n",
+       "    ws.readyState = comm.kernel.ws.readyState;\n",
+       "    function updateReadyState(_event) {\n",
+       "        if (comm.kernel.ws) {\n",
+       "            ws.readyState = comm.kernel.ws.readyState;\n",
+       "        } else {\n",
+       "            ws.readyState = 3; // Closed state.\n",
+       "        }\n",
+       "    }\n",
+       "    comm.kernel.ws.addEventListener('open', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('close', updateReadyState);\n",
+       "    comm.kernel.ws.addEventListener('error', updateReadyState);\n",
+       "\n",
+       "    ws.close = function () {\n",
+       "        comm.close();\n",
+       "    };\n",
+       "    ws.send = function (m) {\n",
+       "        //console.log('sending', m);\n",
+       "        comm.send(m);\n",
+       "    };\n",
+       "    // Register the callback with on_msg.\n",
+       "    comm.on_msg(function (msg) {\n",
+       "        //console.log('receiving', msg['content']['data'], msg);\n",
+       "        var data = msg['content']['data'];\n",
+       "        if (data['blob'] !== undefined) {\n",
+       "            data = {\n",
+       "                data: new Blob(msg['buffers'], { type: data['blob'] }),\n",
+       "            };\n",
+       "        }\n",
+       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
+       "        ws.onmessage(data);\n",
+       "    });\n",
+       "    return ws;\n",
+       "};\n",
+       "\n",
+       "mpl.mpl_figure_comm = function (comm, msg) {\n",
+       "    // This is the function which gets called when the mpl process\n",
+       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+       "\n",
+       "    var id = msg.content.data.id;\n",
+       "    // Get hold of the div created by the display call when the Comm\n",
+       "    // socket was opened in Python.\n",
+       "    var element = document.getElementById(id);\n",
+       "    var ws_proxy = comm_websocket_adapter(comm);\n",
+       "\n",
+       "    function ondownload(figure, _format) {\n",
+       "        window.open(figure.canvas.toDataURL());\n",
+       "    }\n",
+       "\n",
+       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
+       "\n",
+       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+       "    // web socket which is closed, not our websocket->open comm proxy.\n",
+       "    ws_proxy.onopen();\n",
+       "\n",
+       "    fig.parent_element = element;\n",
+       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+       "    if (!fig.cell_info) {\n",
+       "        console.error('Failed to find cell for figure', id, fig);\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.cell_info[0].output_area.element.on(\n",
+       "        'cleared',\n",
+       "        { fig: fig },\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
+       "    var width = fig.canvas.width / fig.ratio;\n",
+       "    fig.cell_info[0].output_area.element.off(\n",
+       "        'cleared',\n",
+       "        fig._remove_fig_handler\n",
+       "    );\n",
+       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
+       "\n",
+       "    // Update the output cell to use the data from the current canvas.\n",
+       "    fig.push_to_output();\n",
+       "    var dataURL = fig.canvas.toDataURL();\n",
+       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+       "    // the notebook keyboard shortcuts fail.\n",
+       "    IPython.keyboard_manager.enable();\n",
+       "    fig.parent_element.innerHTML =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "    fig.close_ws(fig, msg);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
+       "    fig.send_message('closing', msg);\n",
+       "    // fig.ws.close()\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
+       "    // Turn the data on the canvas into data in the output cell.\n",
+       "    var width = this.canvas.width / this.ratio;\n",
+       "    var dataURL = this.canvas.toDataURL();\n",
+       "    this.cell_info[1]['text/html'] =\n",
+       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.updated_canvas_event = function () {\n",
+       "    // Tell IPython that the notebook contents must change.\n",
+       "    IPython.notebook.set_dirty(true);\n",
+       "    this.send_message('ack', {});\n",
+       "    var fig = this;\n",
+       "    // Wait a second, then push the new image to the DOM so\n",
+       "    // that it is saved nicely (might be nice to debounce this).\n",
+       "    setTimeout(function () {\n",
+       "        fig.push_to_output();\n",
+       "    }, 1000);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._init_toolbar = function () {\n",
+       "    var fig = this;\n",
+       "\n",
+       "    var toolbar = document.createElement('div');\n",
+       "    toolbar.classList = 'btn-toolbar';\n",
+       "    this.root.appendChild(toolbar);\n",
+       "\n",
+       "    function on_click_closure(name) {\n",
+       "        return function (_event) {\n",
+       "            return fig.toolbar_button_onclick(name);\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    function on_mouseover_closure(tooltip) {\n",
+       "        return function (event) {\n",
+       "            if (!event.currentTarget.disabled) {\n",
+       "                return fig.toolbar_button_onmouseover(tooltip);\n",
+       "            }\n",
+       "        };\n",
+       "    }\n",
+       "\n",
+       "    fig.buttons = {};\n",
+       "    var buttonGroup = document.createElement('div');\n",
+       "    buttonGroup.classList = 'btn-group';\n",
+       "    var button;\n",
+       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
+       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
+       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
+       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+       "\n",
+       "        if (!name) {\n",
+       "            /* Instead of a spacer, we start a new button group. */\n",
+       "            if (buttonGroup.hasChildNodes()) {\n",
+       "                toolbar.appendChild(buttonGroup);\n",
+       "            }\n",
+       "            buttonGroup = document.createElement('div');\n",
+       "            buttonGroup.classList = 'btn-group';\n",
+       "            continue;\n",
+       "        }\n",
+       "\n",
+       "        button = fig.buttons[name] = document.createElement('button');\n",
+       "        button.classList = 'btn btn-default';\n",
+       "        button.href = '#';\n",
+       "        button.title = name;\n",
+       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
+       "        button.addEventListener('click', on_click_closure(method_name));\n",
+       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
+       "        buttonGroup.appendChild(button);\n",
+       "    }\n",
+       "\n",
+       "    if (buttonGroup.hasChildNodes()) {\n",
+       "        toolbar.appendChild(buttonGroup);\n",
+       "    }\n",
+       "\n",
+       "    // Add the status bar.\n",
+       "    var status_bar = document.createElement('span');\n",
+       "    status_bar.classList = 'mpl-message pull-right';\n",
+       "    toolbar.appendChild(status_bar);\n",
+       "    this.message = status_bar;\n",
+       "\n",
+       "    // Add the close button to the window.\n",
+       "    var buttongrp = document.createElement('div');\n",
+       "    buttongrp.classList = 'btn-group inline pull-right';\n",
+       "    button = document.createElement('button');\n",
+       "    button.classList = 'btn btn-mini btn-primary';\n",
+       "    button.href = '#';\n",
+       "    button.title = 'Stop Interaction';\n",
+       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
+       "    button.addEventListener('click', function (_evt) {\n",
+       "        fig.handle_close(fig, {});\n",
+       "    });\n",
+       "    button.addEventListener(\n",
+       "        'mouseover',\n",
+       "        on_mouseover_closure('Stop Interaction')\n",
+       "    );\n",
+       "    buttongrp.appendChild(button);\n",
+       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
+       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
+       "    var fig = event.data.fig;\n",
+       "    if (event.target !== this) {\n",
+       "        // Ignore bubbled events from children.\n",
+       "        return;\n",
+       "    }\n",
+       "    fig.close_ws(fig, {});\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._root_extra_style = function (el) {\n",
+       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
+       "    // this is important to make the div 'focusable\n",
+       "    el.setAttribute('tabindex', 0);\n",
+       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
+       "    // off when our div gets focus\n",
+       "\n",
+       "    // location in version 3\n",
+       "    if (IPython.notebook.keyboard_manager) {\n",
+       "        IPython.notebook.keyboard_manager.register_events(el);\n",
+       "    } else {\n",
+       "        // location in version 2\n",
+       "        IPython.keyboard_manager.register_events(el);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
+       "    // Check for shift+enter\n",
+       "    if (event.shiftKey && event.which === 13) {\n",
+       "        this.canvas_div.blur();\n",
+       "        // select the cell after this one\n",
+       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+       "        IPython.notebook.select(index + 1);\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
+       "    fig.ondownload(fig, null);\n",
+       "};\n",
+       "\n",
+       "mpl.find_output_cell = function (html_output) {\n",
+       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+       "    // IPython event is triggered only after the cells have been serialised, which for\n",
+       "    // our purposes (turning an active figure into a static one), is too late.\n",
+       "    var cells = IPython.notebook.get_cells();\n",
+       "    var ncells = cells.length;\n",
+       "    for (var i = 0; i < ncells; i++) {\n",
+       "        var cell = cells[i];\n",
+       "        if (cell.cell_type === 'code') {\n",
+       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
+       "                var data = cell.output_area.outputs[j];\n",
+       "                if (data.data) {\n",
+       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
+       "                    data = data.data;\n",
+       "                }\n",
+       "                if (data['text/html'] === html_output) {\n",
+       "                    return [cell, data, j];\n",
+       "                }\n",
+       "            }\n",
+       "        }\n",
+       "    }\n",
+       "};\n",
+       "\n",
+       "// Register the function which deals with the matplotlib target/channel.\n",
+       "// The kernel may be null if the page has been refreshed.\n",
+       "if (IPython.notebook.kernel !== null) {\n",
+       "    IPython.notebook.kernel.comm_manager.register_target(\n",
+       "        'matplotlib',\n",
+       "        mpl.mpl_figure_comm\n",
+       "    );\n",
+       "}\n"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "<img src=\"data:image/png;base64,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7bXXal6XIIi1gQwgQawTqhnA+fn5omNvv/12bNu2Lf9nxhgwRqGQSy+9FOecc07+z2ttAF955RVwOByIxeKiz/fu3YvjjjsOX/va1yqec//+/TjmmGPwb//2b6u+++d//udVRSC5XA6/+tWv8MEPfrBoKfq6664rWm6utGS9fft2SKXS/HGFBhAA7r//fnA4HNhsNgCdN4DPP/88jjnmGExPTwNozAAy5v/ll1+uelw9BtDr9YLD4WDPnj01r0sQxNpABpAg1gnVloBLKd3/xhiDe+65Z9WxN954I3p6evJ/XmsD+NBDD4HD4WBycnLVby688EJccsklFc8ZiUTA4XBw9913r/ruzjvvrJoDODs7i1dffRUf+9jHwOFw8O///u/575ix3rNnDxQKBdRqNTweT9EMJbDaAKZSKRx//PH5WcBOGsB0Oo1TTjml6N+0GQP40ksvVT2uHgPIVAIXbjsgCIJdyAASxDqhWhFIKa0YwCuvvLKsAbzhhhvWlQFk2LdvH84++2wcddRR+b2B9VZclxpAALjvvvvys4CdNIB33303tm3bBrfbjUAggEAggIGBgfw+y0AggL1791Y8N7ME/OSTT1a9h3oMoF6vB4fDweuvv17vX40giA5DBpAg1gntMID1LAF/5StfwQUXXLDquMsvv7zIAMZisYYM4JtvvtnwEvDWrVvbugRcCaZwholfacUAMrOAX/rSlzpqAJnl/2oaHh6ueG6mCKRw/2c5qAiEIA5PyAASxDqhHQawUhHID3/4w/xn//3f/42enp6ifYV2ux2bNm0qMoArKyvgcDi444476rp/iUQCDoeDt956q+hzpgjkmmuuKYoRefrpp9taBOLz+coWfCSTSZx22mnYtm1bPjqnFQMI/H0W8IILLuiYAbRarXjrrbeK1NvbCw6Hg//4j//AW2+9hVQqVfX8l19+OS6//PKqx9QbA7N161aKgSGILoIMIEGsE9phAAtjYHbt2oUTTjgBJ554ImZnZ/PHejwebNq0CRdddBF2796Ne+65ByeffDI+/OEPFxlAADj33HNx6qmnYs+ePXj11VerzgBFIhFs3rwZH/vYx/Diiy/i1VdfRTQaLbrfq6++Grt378Ztt91WdwyMw+HA0UcfjTPOOAMPP/wwfvWrX5WNgXnjjTdw1FFH4dprr8UjjzyC5557Drt27cL73/9+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3d292XB5QECAuP/27dtPnARSUlICQRAQExMDANiwYUOzz6uiogKCIECtVrf4OlOmTMG7777b4n4iao4BkIi6Panuas2ePRs9e/aETCYTmyAIkMlkWLx4cbP3nDx5Mt555502ndOcOXMwf/78NvVtr6CgICgUChw9ehTZ2dlYvnw5bGxsxGC6aNEifPrpp2J/tVoNMzMzBAQEICcnB1u3bjU4YcbGxgYqlZDtBaUAAALRSURBVAoZGRmYPXu23oSZxMREBAYGIi0tDcXFxYiOjsb48ePh7OyMe/fuAQCio6PRo0cPbN++Hfn5+UhJScG0adOgVCpx9+5dAMDevXtx8uRJFBQUIDMzE+vWrUPPnj0RFRX1TK4V0fOKAZCIngtS3NUqKSlBZmam2MLDwyEIAk6cONFs+LaoqAg9evRASEjIE8+lsbERw4YNw8cff9y2k38KgYGBGDBgAORyOVxdXZGYmCjumzhxot4sZeDPkjlDhw6FXC7HiBEjWiyZ07dvXygUCnh5eSEvL0/cn5GRAU9PT9jZ2UGhUGDgwIFYuXIlysrK9F7n559/xpgxY9C7d2+89NJL8Pb2Rk5Ojrjf398fzs7OMDc3h52dHSZNmoSzZ8924pUhMg0MgET0XJDirtbjWhsC9vPzg6Ojozhc/Kjt27cjPDwchYWFSElJwfz582Fubo6srKyOXhYiIoMYAInoudHVd7Ue11IA1Gq16NevH7Zs2WLw99avXy8ed9++fTFz5kykpqa28+yJiNqOAZCIiIjIxDAAEhEREZkYBkAiIiIiE8MASERERGRiGACJiIiITAwDIBEREZGJYQAkIiIiMjEMgEREREQmhgGQiIiIyMQwABIRERGZGAZAIiIiIhPDAEhERERkYhgAiYiIiEwMAyARERGRiWEAJCIiIjIxDIBEREREJoYBkIiIiMjEMAASERERmRgGQCIiIiITwwBIREREZGIYAImIiIhMDAMgERERkYlhACQiIiIyMQyARERERCaGAZCIiIjIxDAAEhEREZkYBkAiIiIiE8MASERERGRiGACJiIiITAwDIBEREZGJYQAkIiIiMjEMgEREREQmhgGQiIiIyMQwABIRERGZGAZAIiIiIhPDAEhERERkYhgAiYiIiEwMAyARERGRiWEAJCIiIjIxDIBEREREJoYBkIiIiMjEMAASERERmZj/B/TbqFOshVEEAAAAAElFTkSuQmCC\" width=\"640\">"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "*c* argument looks like a single numeric RGB or RGBA sequence, which should be avoided as value-mapping will have precedence in case its length matches with *x* & *y*.  Please use the *color* keyword-argument or provide a 2D array with a single row if you intend to specify the same RGB or RGBA value for all points.\n",
+      "*c* argument looks like a single numeric RGB or RGBA sequence, which should be avoided as value-mapping will have precedence in case its length matches with *x* & *y*.  Please use the *color* keyword-argument or provide a 2D array with a single row if you intend to specify the same RGB or RGBA value for all points.\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Plotting 438 external synapses\n",
+      "Missing parameter.json : /media/psf/KTH/PD20220225/parkinson/20220225/pd2/neurons/striatum/dspn/28/parameters.json\n",
+      "Plotting 235 external synapses\n",
+      "Figure written: PD2-network/figures/input-to-1-dSPN_14-and-internal-synapses.png\n"
+     ]
+    }
+   ],
+   "source": [
+    "%matplotlib notebook\n",
+    "from snudda.plotting.plot_degeneration import PlotDegeneration\n",
+    "\n",
+    "pd = PlotDegeneration(original_network_path=network_path_WT,\n",
+    "                      degenerated_network_path=network_path_PD2)\n",
+    "plot_neuron_id = 1\n",
+    "pd.plot_neuron(neuron_id=plot_neuron_id)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "ac5c6283",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3 (ipykernel)",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.7.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/examples/notebooks/Parkinson/dummy-input.json b/examples/notebooks/Parkinson/dummy-input.json
new file mode 100644
index 000000000..51a06eb57
--- /dev/null
+++ b/examples/notebooks/Parkinson/dummy-input.json
@@ -0,0 +1,215 @@
+{
+    "dSPN": {
+	"CorticalBase" : {
+	    "generator" : "poisson",
+	    "type" : "AMPA_NMDA",
+	    "synapseDensity" : "1.15*0.05/(1+exp(-(d-30e-6)/5e-6))",
+	    "frequency" : 2,
+	    "populationUnitCorrelation" : 0.0,
+	    "jitter" : 0.002,
+	    "conductance" : 5e-10,
+	    "modFile": "tmGlut",
+            "nInputs" : {
+		"dSPN_0" : 55,
+		"dSPN_1" : 145,
+		"dSPN_2" : 185,
+		"dSPN_3" : 110
+	    }
+	},
+	"CorticalSignal" : {
+	    "generator" : "poisson",
+	    "start" : 1,
+	    "end" : 1.5,
+	    "type" : "AMPA_NMDA",
+	    "synapseDensity" : "0.45*0.05/(1+exp(-(d-30e-6)/5e-6))",
+	    "frequency" : 10,
+	    "populationUnitCorrelation" : 0.0,
+	    "jitter" : 0.002,
+	    "conductance" : 5e-10,
+	    "modFile": "tmGlut",
+            "nInputs" : {
+		"dSPN_0" : 15,
+		"dSPN_1" : 10,
+		"dSPN_2" : 20,
+		"dSPN_3" : 20 
+	    }
+	},
+	"Thalamic" : {
+	    "generator" : "poisson",	    
+	    "type" : "AMPA_NMDA",
+	    "synapseDensity" : "0.05*exp(-d/200e-6)",
+	    "frequency" : 2,
+	    "populationUnitCorrelation" : 0.0,
+	    "jitter" : 0.01,
+	    "conductance" : 5e-10,
+	    "modFile": "tmGlut",
+            "nInputs" : {
+		"dSPN_0" : 65,
+		"dSPN_1" : 110,
+		"dSPN_2" : 120,
+		"dSPN_3" : 90
+	    }
+	}	
+    },
+
+    "iSPN": {
+	"CorticalBase" : {
+	    "generator" : "poisson",
+	    "type" : "AMPA_NMDA",
+	    "synapseDensity": "0.75*0.052/(1+exp(-(d-30e-6)/5e-6))",
+	    "frequency" : 2,
+	    "populationUnitCorrelation" : 0.0,
+	    "jitter" : 0.003,
+	    "conductance" : 5e-10,
+        "modFile":"tmGlut",
+            "nInputs" : {
+		"iSPN_0" : 70,
+		"iSPN_1" : 80,
+		"iSPN_2" : 40,
+		"iSPN_3" : 180
+	    }
+	},
+	"CorticalSignal" : {
+	    "generator" : "poisson",
+	    "start" : 1.0,
+	    "end" : 1.5,
+	    "type" : "AMPA_NMDA",
+	    "synapseDensity": "0.3*0.052/(1+exp(-(d-30e-6)/5e-6))",
+	    "frequency" : 10,
+	    "populationUnitCorrelation" : 0.0,
+	    "jitter" : 0.003,
+	    "conductance" : 5e-10,
+            "modFile":"tmGlut",
+            "nInputs" : {
+		"iSPN_0" : 20,
+		"iSPN_1" : 10,
+		"iSPN_2" : 20,
+		"iSPN_3" : 10
+	    }
+	},
+	"Thalamic" : {
+	    "generator" : "poisson",	    
+	    "type" : "AMPA_NMDA",
+	    "synapseDensity" : "0.052*exp(-d/200e-6)",
+	    "frequency" : 2,
+	    "populationUnitCorrelation" : 0.0,
+	    "jitter" : 0.01,
+	    "conductance" : 5e-10,
+	    "modFile": "tmGlut",
+	    "nInputs" : {
+		"iSPN_0" : 60,
+		"iSPN_1" : 65,
+		"iSPN_2" : 40 ,
+		"iSPN_3" : 100
+	    }
+	}	
+    },
+
+    
+    "FS": {
+	"Cortical" : {
+	    "generator" : "poisson",	    
+	    "type" : "AMPA_NMDA",
+	    "synapseDensity": "0.092*(1-exp(-d/200e-6))",	    
+	    "frequency" : 2,
+	    "populationUnitCorrelation" : 0.0,
+	    "jitter" : 0.001,
+	    "conductance" : 5e-10,	    
+	    "modFile": "tmGlut",
+	    "nInputs" : {
+		"FS_0" : 190,
+		"FS_1" : 215,
+		"FS_2" : 240,
+		"FS_3" : 210
+	    }
+	},
+	"CorticalSignal" : {
+	    "generator" : "poisson",
+	    "start" : 1.0,
+	    "end" : 1.5,
+	    "type" : "AMPA_NMDA",
+	    "synapseDensity": "0.038*(1-exp(-d/200e-6))",
+	    "frequency" : 10,
+	    "populationUnitCorrelation" : 0.0,
+	    "jitter" : 0.003,
+	    "conductance" : 5e-10,
+	    "modFile":"tmGlut",
+            "nInputs" : {
+		"FS_0" : 50,
+		"FS_1" : 50,
+		"FS_2" : 50,
+		"FS_3" : 50
+	    }
+	},
+	"Thalamic" : {
+	    "generator" : "poisson",	    
+	    "type" : "AMPA_NMDA",
+	    "synapseDensity" : "0.073*exp(-d/200e-6)",	    
+	    "frequency" : 2,
+	    "populationUnitCorrelation" : 0.0,
+	    "jitter" : 0.001,	    
+	    "conductance" : 5e-10,	    
+	    "modFile":"tmGlut",
+	    "nInputs" : {
+		"FS_0" : 180,
+		"FS_1" : 280,
+		"FS_2" : 435,
+		"FS_3" : 265
+	    }
+	}
+
+	
+    },
+
+    "ChIN": {
+	"CorticalSignal" : {
+	    "generator" : "poisson",
+	    "start" : 2.0,
+	    "end" : 2.5,	    
+	    "type" : "AMPA_NMDA",
+	    "synapseDensity": "0.0004*(1-exp(-d/200e-6))",	    
+	    "frequency" : 10,
+	    "populationUnitCorrelation" : 0.0,
+	    "jitter" : 0.001,	    
+	    "conductance" : 5e-10,	    
+	    "modFile": "tmGlut",
+	    "nInputs" : {
+		"ChIN_0" : 10
+	    }
+	},
+	"ThalamicSignal" : {
+	    "generator" : "poisson",
+	    "start" : 1.0,
+	    "end" : 1.5,
+	    "type" : "AMPA_NMDA",
+	    "synapseDensity" : "0.003*exp(-d/200e-6)",	    
+	    "frequency" : 10,
+	    "populationUnitCorrelation" : 0.0,
+	    "jitter" : 0.001,	    
+	    "conductance" : 5e-10,	    
+	    "modFile": "tmGlut",
+	    "nInputs" : {
+		"ChIN_0" : 10
+	    }
+	}
+    },
+
+    "LTS": {
+	"CorticalSignal" : {
+	    "generator" : "poisson",
+	    "start" : 2.0,
+	    "end" : 2.5,
+	    "type" : "AMPA_NMDA",
+	    "synapseDensity": "0.15*0.018*(1-exp(-d/200e-6))",
+	    "frequency" : 10,
+	    "populationUnitCorrelation" : 0.0,
+	    "jitter" : 0.003,
+	    "conductance" : 5e-10,
+	    "modFile":"tmGlut",
+	    "nInputs" : {
+		"LTS_0" : 10
+	    }
+	}
+    }
+    
+}
diff --git a/examples/parallel/KTH_PDC/Dardel_inputTuning/Dardel_inputTuningSetupSimulatePlot.job b/examples/parallel/KTH_PDC/Dardel_inputTuning/Dardel_inputTuningSetupSimulatePlot.job
index e3d443910..dc3404251 100644
--- a/examples/parallel/KTH_PDC/Dardel_inputTuning/Dardel_inputTuningSetupSimulatePlot.job
+++ b/examples/parallel/KTH_PDC/Dardel_inputTuning/Dardel_inputTuningSetupSimulatePlot.job
@@ -43,37 +43,37 @@ neurons_path=$SNUDDA_DATA/neurons/striatum/$neuronType/$singleNeuronType
 #steps=$(($numInputMax-$numInputMin))
 steps=250
 ##################################################################################################
-#srun -n 1 python $SNUDDA_DATA_TOOLS/bgmod2bgdata.py --source $source --morphSource $neurons_path --destination $neurons_path
-#if [ $? != 0 ]; then
-#	echo "Something went wrong during bgmod2bgdata.py aborting!"
-#	exit -1
-#fi
-###################################################################################################
-#input_type=cortical
-#no_meta_input=--no_meta_input
-#echo "STARTING input_tuning setup"
-#echo $NETWORK_DIR --neurons $neurons_path --neuronType $neuronType --singleNeuronType $neurons_path --numInputMin $numInputMin --numInputMax $numInputMax --inputFrequency '[1.0]' --numInputSteps $steps --inputDuration 10.0 --input_type $input_type $no_meta_input 
-#srun -n 1 python $SNUDDA_DIR/input/input_tuning.py setup $NETWORK_DIR --neurons $neurons_path --neuronType $neuronType --singleNeuronType $neurons_path --numInputMin $numInputMin --numInputMax $numInputMax --inputFrequency '[1.0]' --numInputSteps $steps --inputDuration 10.0 --input_type $input_type $no_meta_input 
-#
-#echo "Setup finished"
-#if [ $? != 0 ]; then
-#	echo "Something went wrong during input_tuning setup, aborting!"
-#	exit -1
-#fi
-#
-#echo "Starting simulation job"
-#srun -n 128 $SNUDDA_DIR/../examples/parallel/KTH_PDC/Dardel_inputTuning/x86_64/special -mpi -python $SNUDDA_DIR/input/input_tuning.py simulate $NETWORK_DIR
-#
-#if [ $? != 0 ]; then
-#	echo "Something went wrong during input_tuning simulation, aborting!"
-#	exit -1
-#fi
-#
-#srun -n 1 python $SNUDDA_DIR/input/input_tuning.py analyse $NETWORK_DIR --input_type $input_type
-#if [ $? != 0 ]; then
-#	echo "Something went wrong during input_tuning analyse, aborting!"
-#	exit -1
-#fi
+srun -n 1 python $SNUDDA_DATA_TOOLS/bgmod2bgdata.py --source $source --morphSource $neurons_path --destination $neurons_path
+if [ $? != 0 ]; then
+	echo "Something went wrong during bgmod2bgdata.py aborting!"
+	exit -1
+fi
+##################################################################################################
+input_type=cortical
+no_meta_input=--no_meta_input
+echo "STARTING input_tuning setup"
+echo $NETWORK_DIR --neurons $neurons_path --neuronType $neuronType --singleNeuronType $neurons_path --numInputMin $numInputMin --numInputMax $numInputMax --inputFrequency '[1.0]' --numInputSteps $steps --inputDuration 10.0 --input_type $input_type $no_meta_input 
+srun -n 1 python $SNUDDA_DIR/input/input_tuning.py setup $NETWORK_DIR --neurons $neurons_path --neuronType $neuronType --singleNeuronType $neurons_path --numInputMin $numInputMin --numInputMax $numInputMax --inputFrequency '[1.0]' --numInputSteps $steps --inputDuration 10.0 --input_type $input_type $no_meta_input 
+
+echo "Setup finished"
+if [ $? != 0 ]; then
+	echo "Something went wrong during input_tuning setup, aborting!"
+	exit -1
+fi
+
+echo "Starting simulation job"
+srun -n 128 $SNUDDA_DIR/../examples/parallel/KTH_PDC/Dardel_inputTuning/x86_64/special -mpi -python $SNUDDA_DIR/input/input_tuning.py simulate $NETWORK_DIR
+
+if [ $? != 0 ]; then
+	echo "Something went wrong during input_tuning simulation, aborting!"
+	exit -1
+fi
+
+srun -n 1 python $SNUDDA_DIR/input/input_tuning.py analyse $NETWORK_DIR --input_type $input_type
+if [ $? != 0 ]; then
+	echo "Something went wrong during input_tuning analyse, aborting!"
+	exit -1
+fi
 
 srun -n 1 python $SNUDDA_DIR/plotting/plot_network_simulation.py --nametag $NETWORK_NAME --doHistRast 0 --doTraces 1 --doInpRast 1 --inputFile "input.hdf5" --input_type $input_type --neuronType $neuronType
 if [ $? != 0 ]; then
@@ -81,7 +81,7 @@ if [ $? != 0 ]; then
 	exit -1
 fi
 
-srun -n 1 python $SNUDDA_DATA_TOOLS/analyse_data_and_create_meta.py $NETWORK_DIR --networkName $NETWORK_NAME --neuronsPath $neurons_path --input_type $input_type --neuronType $neuronType --singleNeuronType $singleNeuronType
+srun -n 1 python $SNUDDA_DATA_TOOLS/analyse_data_and_create_meta.py $NETWORK_DIR --networkName $NETWORK_NAME --neuronsPath $neurons_path --input_type $input_type --neuronType $neuronType --singleNeuronType $singleNeuronType --snudda_data_tools $SNUDDA_DATA_TOOLS
 if [ $? != 0 ]; then
 	echo "Something went wrong during analyse_data_and_create_meta.py aborting!"
 	exit -1
@@ -118,7 +118,7 @@ if [ $? != 0 ]; then
 	exit -1
 fi
 
-srun -n 1 python $SNUDDA_DATA_TOOLS/analyse_data_and_create_meta.py $NETWORK_DIR --networkName $NETWORK_NAME --neuronsPath $neurons_path --input_type $input_type --neuronType $neuronType --singleNeuronType $singleNeuronType
+srun -n 1 python $SNUDDA_DATA_TOOLS/analyse_data_and_create_meta.py $NETWORK_DIR --networkName $NETWORK_NAME --neuronsPath $neurons_path --input_type $input_type --neuronType $neuronType --singleNeuronType $singleNeuronType --snudda_data_tools $SNUDDA_DATA_TOOLS
 if [ $? != 0 ]; then
 	echo "Something went wrong during analyse_data_and_create_meta.py aborting!"
 	exit -1
@@ -142,6 +142,7 @@ if [ $? != 0 ]; then
 	exit -1
 fi
 
+sleep 5 #To avoid crash that happens at this point sometimes: "srun: error: Unable to create step for job 198913: Job/step already completing or completed"
 input_type=corticothalamic #used as dummy to name figures now, but perhaps implement later to tune both types of inputs in one go (perhaps use no_meta_input)
 srun -n 1 python $SNUDDA_DIR/input/input_tuning.py analyse $NETWORK_DIR --input_type $input_type
 if [ $? != 0 ]; then
diff --git a/examples/parallel/KTH_PDC/Dardel_inputTuning/Dardel_transfer2Meta.job b/examples/parallel/KTH_PDC/Dardel_inputTuning/Dardel_transfer2Meta.job
index f93613d04..9e5a8f936 100644
--- a/examples/parallel/KTH_PDC/Dardel_inputTuning/Dardel_transfer2Meta.job
+++ b/examples/parallel/KTH_PDC/Dardel_inputTuning/Dardel_transfer2Meta.job
@@ -38,7 +38,7 @@ export PYTHONPATH=$LN/lib/python:$PYTHONPATH
 
 echo "STARTING analyse_data_and_create_meta.py"
 neurons_path=$SNUDDA_DATA/neurons/striatum/$neuronType/$singleNeuronType
-srun python $SNUDDA_DATA_TOOLS/analyse_data_and_create_meta.py $NETWORK_DIR --networkName $NETWORK_NAME --neuronsPath $neurons_path --input_type $input_type --neuronType $neuronType --singleNeuronType $singleNeuronType
+srun python $SNUDDA_DATA_TOOLS/analyse_data_and_create_meta.py $NETWORK_DIR --networkName $NETWORK_NAME --neuronsPath $neurons_path --input_type $input_type --neuronType $neuronType --singleNeuronType $singleNeuronType --snudda_data_tools $SNUDDA_DATA_TOOLS
 if [ $? != 0 ]; then
 	echo "Something went wrong during analyse_data_and_create_meta.py aborting!"
 	exit -1
diff --git a/requirements.txt b/requirements.txt
index 5d9f0d606..6cc388e14 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -17,4 +17,4 @@ setuptools
 psutil >= 5.8.0
 cython  # Needed for compiling NEURON
 numba>=0.55.1  # Optimisation
-
+# igraph
diff --git a/setup.py b/setup.py
index 79283a320..a13117e10 100644
--- a/setup.py
+++ b/setup.py
@@ -33,7 +33,8 @@
         "psutil",
         "argparse",
         "numexpr>=2.7.3",
-        "numba>=0.53.1"
+        "numba>=0.53.1",
+        # "igraph"
     ]
     
 setuptools.setup(
diff --git a/snudda/__init__.py b/snudda/__init__.py
index e13852f16..869e61117 100644
--- a/snudda/__init__.py
+++ b/snudda/__init__.py
@@ -1,6 +1,6 @@
 from .core import Snudda
 
-__version__ = "1.2.17"
+__version__ = "1.2.18"
 
 from .init import SnuddaInit
 from .place import SnuddaPlace
diff --git a/snudda/analyse/analyse.py b/snudda/analyse/analyse.py
index e448c5e32..df9fe7e88 100644
--- a/snudda/analyse/analyse.py
+++ b/snudda/analyse/analyse.py
@@ -1,22 +1,20 @@
 # This script is custom written to handle very large datasets. It does so by
 # not keeping all the information in memory, instead parsing the HDF5
 # piece by piece
-from collections import OrderedDict
-
-import numpy as np
-import scipy.sparse as sps
-import h5py
-import timeit
-import time
-from glob import glob
+import json
 import os
 import sys
-import json
+import time
+import timeit
+from collections import OrderedDict
+from glob import glob
 
+import h5py
 import matplotlib
-import matplotlib.pyplot as plt
 import matplotlib.patches as patches
-from mpl_toolkits.mplot3d import Axes3D
+import matplotlib.pyplot as plt
+import numpy as np
+import scipy.sparse as sps
 
 from snudda.utils.load import SnuddaLoad
 
@@ -43,7 +41,7 @@ def __init__(self,
         self.debug = False
         self.show_plots = show_plots
 
-        print("Assuming volume type: " + str(volume_type) + "[cube or full]")
+        print(f"Assuming volume type: {volume_type} [cube or full]")
 
         self.volume_type = volume_type
         self.close_plots = close_plots
@@ -54,7 +52,7 @@ def __init__(self,
             elif volume_type == "full":
                 n_max_analyse = 20000
 
-        print("Only using " + str(n_max_analyse) + "neurons of the connection data")
+        print(f"Only using {n_max_analyse} neurons of the connection data")
 
         self.num_max_analyse = n_max_analyse
 
@@ -63,9 +61,6 @@ def __init__(self,
         self.all_types = None
         self.neuron_type_id = None
 
-        if hdf5_file is None or hdf5_file == "last":
-            hdf5_file = self.find_latest_file()
-
         base_dir = os.path.dirname(hdf5_file)
         assert os.path.isdir(base_dir), \
             f"Internal inconsistency. Not a directory {base_dir}, derived from hdf5_file{hdf5_file}"
@@ -101,7 +96,7 @@ def __init__(self,
 
         if not cache_loaded:
             self.num_neurons = self.network["nNeurons"]
-            print("Number of neurons: " + str(self.num_neurons))
+            print(f"Number of neurons: {self.num_neurons}")
 
             # GABA connection matrix (synType = 1) (ignore AMPA/NMDA = 2, GJ = 3)
             # self.connectionMatrix = self.createConnectionMatrix(synType=1,
@@ -155,9 +150,9 @@ def save_cache_data(self, hdf5_file):
 
         import h5py
 
-        cache_file = hdf5_file + "-cache"
+        cache_file = f"{hdf5_file}-cache"
 
-        print("Saving cache to " + cache_file)
+        print(f"Saving cache to {cache_file}")
         out_file = h5py.File(cache_file, 'w', libver='latest')
 
         # Connection Matrix
@@ -196,17 +191,14 @@ def save_cache_data(self, hdf5_file):
 
             dend_pos_bin = dict([])
             for prePost in self.dend_position_bin:
-                pp = self.all_types[prePost[0]] + "_" + self.all_types[prePost[1]]
+                pp = f"{self.all_types[prePost[0]]}_{self.all_types[prePost[1]]}"
                 dend_pos_bin[pp] = list(self.dend_position_bin[prePost])
 
-            out_file.create_dataset("dendPositionBin",
-                                    data=json.dumps(dend_pos_bin))
-            out_file.create_dataset("dendPositionEdges",
-                                    data=self.dend_position_edges)
+            out_file.create_dataset("dendPositionBin", data=json.dumps(dend_pos_bin))
+            out_file.create_dataset("dendPositionEdges", data=self.dend_position_edges)
 
             all_types = [x.encode("ascii", "ignore") for x in self.all_types]
-            out_file.create_dataset("allTypes",
-                                   data=all_types)
+            out_file.create_dataset("allTypes", data=all_types)
             out_file.create_dataset("neuronTypeID", data=self.neuron_type_id)
 
             out_file.create_dataset("nMaxAnalyse", data=self.num_max_analyse)
@@ -230,7 +222,7 @@ def load_cache_data(self, hdf5_file):
         import os
         import h5py
 
-        cache_file = hdf5_file + "-cache"
+        cache_file = f"{hdf5_file}-cache"
         data_loaded = False
 
         if os.path.exists(cache_file):
@@ -239,7 +231,7 @@ def load_cache_data(self, hdf5_file):
 
             # Make sure cache file is newer than data file
             if t_cache > t_orig:
-                print("Loading from " + cache_file)
+                print(f"Loading from {cache_file}")
 
                 try:
                     with h5py.File(cache_file, 'r') as data:
@@ -330,9 +322,8 @@ def create_connection_matrix(self, chunk_size=1000000,
 
         for synapses in self.network_load.synapse_iterator(chunk_size=chunk_size):
 
-            print("Synapse row " + str(row_ctr)
-                  + " - " + str(100 * row_ctr / float(num_syn_total)) + " %"
-                  + " time: " + str(timeit.default_timer() - t0) + " seconds")
+            print(f"Synapse row {row_ctr} - {100 * row_ctr / float(num_syn_total)} % "
+                  f"time: {timeit.default_timer() - t0} seconds")
 
             for synRow in synapses:
 
@@ -369,7 +360,7 @@ def create_connection_matrix(self, chunk_size=1000000,
 
         t1 = timeit.default_timer()
 
-        print("Created connection matrix " + str(t1 - t0) + " seconds")
+        print(f"Created connection matrix {t1 - t0} seconds")
 
         return sps.csr_matrix(connection_matrix, dtype=np.int16)
 
@@ -414,7 +405,7 @@ def create_connection_matrix_gj(self):
             last_count = 0
 
         t1 = timeit.default_timer()
-        print("Created gap junction connection matrix " + str(t1 - t0) + " seconds")
+        print(f"Created gap junction connection matrix {t1 - t0} seconds")
 
         return sps.csr_matrix(connection_matrix_gj, dtype=np.int16)
 
@@ -475,7 +466,7 @@ def get_sub_pop(self, volume_type="cube", volume_part="centre", side_len=None,
                                                 volume_id=volume_id)
         else:
 
-            print("Unknown volume type: " + str(volume_type))
+            print(f"Unknown volume type: {volume_type}")
             import pdb
             pdb.set_trace()
 
@@ -489,8 +480,7 @@ def get_sub_pop(self, volume_type="cube", volume_part="centre", side_len=None,
                 try:
                     keep_idx = np.linspace(0, len(neuron_id), num_max_analyse,
                                            endpoint=False, dtype=int)
-                    print("Returning subset of neurons to analyse:"
-                          + str(len(keep_idx)) + "/" + str(len(neuron_id)))
+                    print(f"Returning subset of neurons to analyse: {len(keep_idx)}/{len(neuron_id)}")
                     neuron_id = np.array([neuron_id[x] for x in keep_idx])
                 except:
                     import traceback
@@ -554,14 +544,14 @@ def centre_neurons(self, side_len=None, neuron_id=None, volume_id="Striatum"):
 
             assert volume_id is None \
                    or self.network["neurons"][nid]["volumeID"] == volume_id, \
-                   "Neuron " + str(nid) + " does not belong to volumeID " + str(volume_id)
+                f"Neuron {nid} does not belong to volumeID {volume_id}"
 
             if (abs(pos[0] - x_centre) <= side_len
                     and abs(pos[1] - y_centre) <= side_len
                     and abs(pos[2] - z_centre) <= side_len):
                 c_id.append(nid)
 
-        print("Centering in " + str(volume_id) + " : Keeping " + str(len(c_id)) + "/" + str(len(neuron_id)))
+        print(f"Centering in {volume_id} : Keeping {len(c_id)}/{len(neuron_id)}")
 
         return c_id
 
@@ -584,7 +574,7 @@ def corner_neurons(self, side_len=None, neuron_id=None, volume_id="Striatum"):
                             for x in self.network["neurons"]])[0]
 
         if len(idx) == 0:
-            print("No neurons found in volume " + str(volume_id))
+            print(f"No neurons found in volume {volume_id}")
 
             import pdb
             pdb.set_trace()
@@ -626,7 +616,7 @@ def corner_neurons(self, side_len=None, neuron_id=None, volume_id="Striatum"):
                     and (pos[2] <= z_min + side_len or pos[2] >= z_max - side_len)):
                 c_id.append(nid)
 
-        print("Taking corner neurons: Keeping " + str(len(c_id)) + "/" + str(len(neuron_id)))
+        print(f"Taking corner neurons: Keeping {len(c_id)}/{len(neuron_id)}")
 
         if False:
 
@@ -659,7 +649,7 @@ def save_figure(self, plt, fig_name, fig_type="pdf"):
             print(f"save_figures: Creating directory {self.fig_dir}")
             os.mkdir(self.fig_dir)
 
-        full_fig_name = self.fig_dir + "/" + fig_name + "." + fig_type
+        full_fig_name = os.path.join(self.fig_dir, f"{fig_name }.{fig_type}")
 
         # Remove part of the frame
         plt.gca().spines["right"].set_visible(False)
@@ -726,7 +716,7 @@ def plot_num_synapses_per_pair(self, pre_type, post_type, side_len=None,
 
         # The prune tuning func might set data to 0, we want to exclude those
         mean_synapses = float(np.sum(con_mat[pre_pop, :][:, post_pop].data)) \
-                              / np.sum(con_mat[pre_pop, :][:, post_pop].data != 0)
+                        / np.sum(con_mat[pre_pop, :][:, post_pop].data != 0)
 
         con = con_mat[pre_pop, :][:, post_pop]
 
@@ -752,7 +742,7 @@ def plot_num_synapses_per_pair(self, pre_type, post_type, side_len=None,
 
         plt.xlabel("Number of " + connection_type)
         plt.ylabel('Probability density')
-        plt.title(self.neuron_name(pre_type) + " to " + self.neuron_name(post_type))
+        plt.title(f"{self.neuron_name(pre_type)} to {self.neuron_name(post_type)}")
 
         plt.tight_layout()
         plt.draw()
@@ -871,15 +861,15 @@ def plot_connection_probability(self,
 
         if not exp_data:
             if exp_data_detailed:
-                exp_data = [x[0]/x[1] for x in exp_data_detailed]
+                exp_data = [x[0] / x[1] for x in exp_data_detailed]
             else:
                 exp_data = []
 
         if not exp_data_detailed:
             exp_data_detailed = None
         else:
-            assert (np.array(exp_data) == np.array([x[0]/x[1] for x in exp_data_detailed])).all(), \
-                f"exp_data = {exp_data }and exp_data_detailed {exp_data_detailed} do not match"
+            assert (np.array(exp_data) == np.array([x[0] / x[1] for x in exp_data_detailed])).all(), \
+                f"exp_data = {exp_data} and exp_data_detailed = {exp_data_detailed} do not match"
 
         if side_len is None:
             side_len = self.side_len
@@ -952,7 +942,7 @@ def plot_connection_probability(self,
 
             p_model = float(cnt) / float(cnt_all)
 
-            print("P(d<" + str(d_limit) + ")=" + str(p_model))
+            print(f"P(d<{d_limit}) = {p_model}")
             # ax = fig.get_axes()
 
             # Also add errorbars
@@ -974,19 +964,9 @@ def plot_connection_probability(self,
                 bar_centre = (ns + (z ** 2) / 2) / (n + z * 2)
                 bar_height = z / (n + z ** 2) * np.sqrt((ns * (n - ns) / n + (z ** 2) / 4))
 
-                # plt.errorbar(dLimit*1e6/2,P,stdExp,color="gray",
-                #             elinewidth=1,capsize=5)
                 plt.errorbar(d_limit * 1e6 / 2, bar_centre, bar_height, color="gray",
                              elinewidth=1, capsize=5)
 
-                # import pdb
-                # pdb.set_trace()
-
-                # rectExpStd = patches.Rectangle((0,P-stdExp),
-                #                               width=dLimit*1e6,height=2*stdExp,
-                #                               alpha=0.2,linewidth=0,
-                #                               color="red",fill=True)
-                # ax.add_patch(rectExpStd)
             else:
                 std_exp = 0
 
@@ -1007,22 +987,6 @@ def plot_connection_probability(self,
                 if self.show_plots:
                     plt.show()
 
-                # rectExp = patches.Rectangle((0,0), dLimit*1e6, Pexp, \
-                #                            linewidth=2,color='red',fill=False)
-                # ax.add_patch(rectExp)
-
-            if False:  #
-                # Show the binning from the model data
-                plt.plot([0, d_limit * 1e6], [p_model, p_model], color="blue", linewidth=2)
-
-            # rect = patches.Rectangle((0,0), dLimit*1e6, P, \
-            #                         linewidth=1,color='blue',fill=False)
-            # ax.add_patch(rect)
-
-            if False:
-                plt.text(d_limit * 1e6, p_model,
-                         "P(d<" + str(d_limit * 1e6) + ")=%.3f" % p_model, size=9)
-
         # Draw the curve itself
         if draw_step:
             plt.step(dist * 1e6, p_con, color='black', linewidth=2, where="post")
@@ -1035,11 +999,6 @@ def plot_connection_probability(self,
 
         label_size = 22
 
-        # if(dist_3d):
-        #  plt.xlabel("Distance ($\mu$m)",fontsize=labelSize)
-        # else:
-        #  plt.xlabel("2D Distance ($\mu$m)",fontsize=labelSize)
-
         # Hack to avoid divide by zero
         count_all_b = count_all.copy()
         count_all_b[count_all_b == 0] = 1.0
@@ -1048,10 +1007,10 @@ def plot_connection_probability(self,
         z = 1.96
 
         p_centre = np.array([(ns + (z ** 2) / 2) / (n + z * 2)
-                            for (ns, n) in zip(count_con, count_all_b)]).flatten()
+                             for (ns, n) in zip(count_con, count_all_b)]).flatten()
         p_height = np.array([z / (n + z ** 2)
-                            * np.sqrt((ns * (n - ns) / n + (z ** 2) / 4))
-                            for (ns, n) in zip(count_con, count_all_b)]).flatten()
+                             * np.sqrt((ns * (n - ns) / n + (z ** 2) / 4))
+                             for (ns, n) in zip(count_con, count_all_b)]).flatten()
 
         # Use the last bin larger than xMax as the end
         d_idx = np.where(dist * 1e6 > x_max)[0][0]
@@ -1060,9 +1019,9 @@ def plot_connection_probability(self,
         p_max = p_centre + p_height
 
         if draw_step:
-          plt.fill_between(dist[:d_idx] * 1e6, p_min[:d_idx], p_max[:d_idx],
-                           color='grey', step="post",
-                           alpha=0.4)
+            plt.fill_between(dist[:d_idx] * 1e6, p_min[:d_idx], p_max[:d_idx],
+                             color='grey', step="post",
+                             alpha=0.4)
         else:
             plt.fill_between((dist[:d_idx] + d_half_step) * 1e6, p_min[:d_idx], p_max[:d_idx],
                              color='grey', step=None,
@@ -1071,15 +1030,6 @@ def plot_connection_probability(self,
         plt.xlabel("Distance ($\mu$m)", fontsize=label_size)
         plt.ylabel("Con Prob (%)", fontsize=label_size)
 
-        # Adjust axis if needed
-        # import pdb
-        # pdb.set_trace()
-
-        # Set plot limits
-        # if(any(x is not None for x in expData)):
-        #  if(max(plt.ylim()) < max(expData+stdExp)):
-        #    plt.ylim([0, np.ceil(max(expData+stdExp)*10)/10])
-
         if x_max is not None:
             plt.xlim([0, x_max])
 
@@ -1165,7 +1115,7 @@ def plot_connection_probability_channels(self,
         if len(exp_data_detailed) == 0:
             exp_data_detailed = []
             for x in exp_data:
-              exp_data_detailed.append(None)
+                exp_data_detailed.append(None)
 
         assert pre_type is not None
         assert post_type is not None
@@ -1209,12 +1159,6 @@ def plot_connection_probability_channels(self,
         plt.xticks(fontsize=12, rotation=0)
         plt.yticks(fontsize=12, rotation=0)
 
-        # plt.tick_params(axis='both', which='major', labelsize=10)
-        # plt.tick_params(axis='both', which='minor', labelsize=8)
-
-        # import pdb
-        # pdb.set_trace()
-
         # Add lines for experimental data and matching data for model
         for (dLimit, Pexp, expNum) in zip(exp_max_dist, exp_data, exp_data_detailed):
             cnt_within = 0
@@ -1272,45 +1216,21 @@ def plot_connection_probability_channels(self,
                     # Add P-line on top
                     ax.add_patch(rect_exp)
 
-            if False:
-                rect_within = patches.Rectangle((0, 0), dLimit * 1e6, p_within,
-                                                linewidth=1, color='blue', fill=False)
-                rect_between = patches.Rectangle((0, 0), dLimit * 1e6, p_between,
-                                                 linewidth=1, color='lightblue',
-                                                 fill=False)
-                rect_total = patches.Rectangle((0, 0), dLimit * 1e6, p_total,
-                                               linewidth=2, color='blue', fill=False)
-
-                ax.add_patch(rect_within)
-                ax.add_patch(rect_between)
-                ax.add_patch(rect_total)
-
-            if True:
-                # Draw binned data as lines instead
-                plt.plot([0, dLimit * 1e6], [p_within, p_within],
-                         color="blue", linewidth=1)
-                plt.plot([0, dLimit * 1e6], [p_between, p_between],
-                         color="lightblue", linewidth=1)
-                plt.plot([0, dLimit * 1e6], [p_total, p_total],
-                         color="blue", linewidth=2)
-
-            if False:
-                Plt(dLimit * 1e6, p_within, "Pw(d<" + str(dLimit * 1e6) + ")=%.3f" % p_within, size=9)
-                plt.text(dLimit * 1e6, p_between, "Pb(d<" + str(dLimit * 1e6) + ")=%.3f" % p_between, size=9)
-
-        # Adjust axis if needed
-        # import pdb
-        # pdb.set_trace()
+            # Draw binned data as lines instead
+            plt.plot([0, dLimit * 1e6], [p_within, p_within],
+                     color="blue", linewidth=1)
+            plt.plot([0, dLimit * 1e6], [p_between, p_between],
+                     color="lightblue", linewidth=1)
+            plt.plot([0, dLimit * 1e6], [p_total, p_total],
+                     color="blue", linewidth=2)
 
         if any(x is not None for x in exp_data):
             if max(plt.ylim()) < max(exp_data):
                 plt.ylim([0, np.ceil(max(exp_data) * 10) / 10])
 
         plt.xlim([0, 250])
-        # plt.xlim([0, 1000])
 
-        plt.title(self.neuron_name(pre_type) + " to "
-                  + self.neuron_name(post_type) + " connections")
+        plt.title(f"{self.neuron_name(pre_type)} to {self.neuron_name(post_type)} connections")
 
         plt.tight_layout()
         plt.ion()
@@ -1321,9 +1241,7 @@ def plot_connection_probability_channels(self,
         else:
             proj_text = '-2D-dist'
 
-        fig_name = 'Network-distance-dependent-connection-probability-channels-' \
-                   + str(pre_type) + "-to-" + str(post_type) \
-                   + proj_text
+        fig_name = f"Network-distance-dependent-connection-probability-channels-{pre_type}-to-{post_type}{proj_text}"
 
         self.save_figure(plt, fig_name)
 
@@ -1336,7 +1254,7 @@ def plot_connection_probability_channels(self,
 
     def connection_probability_wrapper(self, pre_id, post_id, num_bins=86, dist_3d=True):
 
-        print("Worker started, preID: " + str(pre_id))
+        print(f"Worker started, preID: {pre_id}")
 
         (dist, p_con, count_con, count_all) = self.connection_probability(pre_id,
                                                                           post_id,
@@ -1373,7 +1291,7 @@ def connection_probability(self,
         elif connection_type == "gapjunctions":
             con_mat = self.connection_matrix_gj
         else:
-            assert False,"Unknown connection_type: " + str(connection_type)
+            assert False, "Unknown connection_type: " + str(connection_type)
 
         # Make this loop use threads, to speed it up
 
@@ -1427,14 +1345,14 @@ def connection_probability(self,
             t_b = timeit.default_timer()
 
             if self.debug:
-                print(str(xi + 1) + "/" + str(len(pre_id)) + " " + str(t_b - t_a) + "s")
+                print(f"{xi + 1}/{len(pre_id)} {t_b - t_a} s")
 
         p_con = np.divide(count_con, count_all)
 
-        print("Requested: " + str(num_points) + " calculated " + str(sum(count_all)))
+        print(f"Requested: {num_points} calculated {sum(count_all)}")
 
         if not dist_3d:
-            print("Rejected (too large z-depth): " + str(count_rejected))
+            print(f"Rejected (too large z-depth): {count_rejected}")
 
         # import pdb
         # pdb.set_trace()
@@ -1512,8 +1430,6 @@ def connection_probability_population_units(self,
                     count_rejected += 1
                     continue
 
-                # assert (idx < nBins), "Idx too large " + str(idx)
-
                 same_population_unit_flag = (population_unit[x] == population_unit[y])
 
                 if self.connection_matrix[x, y] > 0:
@@ -1530,17 +1446,16 @@ def connection_probability_population_units(self,
             t_b = timeit.default_timer()
 
             if self.debug:
-                print(str(xi + 1) + "/" + str(len(pre_id)) + " " + str(t_b - t_a) + "s")
+                print(f"{xi + 1}/{len(pre_id)} {t_b - t_a} s")
 
         pcon_within_pop_unit = np.divide(count_con_within_channel, count_all_within_pop_unit)
         pcon_between_pop_unit = np.divide(count_con_between_pop_units,
                                           count_all_between_pop_units)
 
-        print("Requested: " + str(num_points) + " calculated " + str(
-            sum(count_all_within_pop_unit) + sum(count_all_between_pop_units)))
+        print(f"Requested: {num_points} calculated {sum(count_all_within_pop_unit) + sum(count_all_between_pop_units)}")
 
         if not dist_3d:
-            print("Rejected (too large z-depth): " + str(count_rejected))
+            print(f"Rejected (too large z-depth): {count_rejected}")
 
         return (dist, pcon_within_pop_unit, pcon_between_pop_unit,
                 count_con_within_channel, count_con_between_pop_units,
@@ -1555,8 +1470,7 @@ def num_incoming_connections(self, neuron_type, pre_type, side_len=None,
         if side_len is None:
             side_len = 100e-6
 
-        print("Calculating number of incoming connections " + pre_type
-              + " -> " + neuron_type)
+        print(f"Calculating number of incoming connections {pre_type} -> {neuron_type}")
 
         # Only use post synaptic cell in central part of structure,
         # to minimize edge effect
@@ -1571,14 +1485,14 @@ def num_incoming_connections(self, neuron_type, pre_type, side_len=None,
 
         pre_id = self.populations[pre_type]
 
-        print("#pre = " + str(len(pre_id)) + ", #post = " + str(len(neuron_id)))
+        print(f"#pre = {len(pre_id)}, #post = {len(neuron_id)}")
 
         if connection_type == "synapses":
             con_mat = self.connection_matrix
         elif connection_type == "gapjunctions":
             con_mat = self.connection_matrix_gj
         else:
-            assert "Unknown connection_type: " + str(connection_type)
+            assert f"Unknown connection_type: {connection_type}"
             con_mat = None  # To get pycharm to shut up ;)
 
         n_con = np.zeros((len(neuron_id), 1))
@@ -1601,13 +1515,11 @@ def plot_incoming_connections(self, pre_type, neuron_type, side_len=None,
                                   num_bins=None):
 
         if pre_type not in self.populations:
-            print("plotIncomingConnections: " + str(pre_type)
-                  + " is not in the simulation")
+            print(f"plot_incoming_connections: {pre_type} is not in the simulation")
             return
 
         if neuron_type not in self.populations:
-            print("plotIncomingConnections: " + str(neuron_type)
-                  + " is not in the simulation")
+            print(f"plot_incoming_connections: {neuron_type} is not in the simulation")
             return
 
         (n_con, nSyn) = self.num_incoming_connections(neuron_type=neuron_type,
@@ -1650,8 +1562,7 @@ def plot_incoming_connections(self, pre_type, neuron_type, side_len=None,
 
         plt.xlabel("Number of connected neighbours")
         plt.ylabel("Probability density")
-        plt.title(self.neuron_name(pre_type) + " connecting to "
-                  + self.neuron_name(neuron_type))
+        plt.title(f"{self.neuron_name(pre_type)} connecting to {self.neuron_name(neuron_type)}")
         plt.tight_layout()
         xleft, xright = plt.xlim()
         plt.xlim(0, xright)
@@ -1659,8 +1570,7 @@ def plot_incoming_connections(self, pre_type, neuron_type, side_len=None,
         plt.ion()
         plt.draw()
 
-        fig_name = "Network-" + connection_type + "-input-to-" \
-                   + neuron_type + "-from-" + pre_type
+        fig_name = f"Network-{connection_type}-input-to-{neuron_type}-from-{pre_type}"
 
         self.save_figure(plt, fig_name)
 
@@ -1686,10 +1596,9 @@ def plot_incoming_connections(self, pre_type, neuron_type, side_len=None,
                      align="left", density=True,
                      color=self.get_neuron_color(pre_type))
 
-        plt.xlabel("Number of incoming " + connection_type)
+        plt.xlabel(f"Number of incoming {connection_type}")
         plt.ylabel("Probability density")
-        plt.title(self.neuron_name(pre_type) + " " + connection_type
-                  + " on " + self.neuron_name(neuron_type))
+        plt.title(f"{self.neuron_name(pre_type)} {connection_type} on {self.neuron_name(neuron_type)}")
         plt.tight_layout()
 
         xleft, xright = plt.xlim()
@@ -1698,7 +1607,7 @@ def plot_incoming_connections(self, pre_type, neuron_type, side_len=None,
         plt.ion()
         plt.draw()
 
-        fig_name = "Network-" + connection_type + "-to-" + neuron_type + "-from-" + pre_type
+        fig_name = f"Network-{connection_type}-to-{neuron_type}-from-{pre_type}"
 
         self.save_figure(plt, fig_name)
 
@@ -1713,7 +1622,7 @@ def plot_incoming_connections(self, pre_type, neuron_type, side_len=None,
 
     def find_synapses(self, neuron_id, max_synapses=10000, chunk_size=1000000):
 
-        print("Finding synapses between: " + str(neuron_id))
+        print(f"Finding synapses between: {neuron_id}")
 
         synapses = np.zeros((max_synapses, 8))
         synapse_ctr = 0
@@ -1726,17 +1635,16 @@ def find_synapses(self, neuron_id, max_synapses=10000, chunk_size=1000000):
 
         for rowEnd in np.linspace(chunk_size, num_rows, num_steps, dtype=int):
 
-            print("Rows: " + str(row_start) + ":" + str(rowEnd)
-                  + " total: " + str(num_rows))
+            print(f"Rows: {row_start}:{rowEnd} total: {num_rows}")
 
             syn = self.data["network/synapses"][row_start:rowEnd, :]
 
-            for synRow in syn:
-                if synRow[0] in neuron_id and synRow[1] in neuron_id:
-                    synapses[synapse_ctr, :] = synRow
+            for syn_row in syn:
+                if syn_row[0] in neuron_id and syn_row[1] in neuron_id:
+                    synapses[synapse_ctr, :] = syn_row
                     synapse_ctr += 1
 
-        print("Found " + str(synapse_ctr) + " synapses")
+        print(f"Found {synapse_ctr} synapses")
 
         print(str(synapses[0:synapse_ctr, :]))
 
@@ -1751,15 +1659,14 @@ def plot_neurons(self, neuron_id, show_synapses=True, plot_pre_neurons=True):
         axis = None
 
         # Finding synapses, this might take time
-        (synapses, synapse_coords) = self.network_load.find_synapses(postID=neuron_id)
+        (synapses, synapse_coords) = self.network_load.find_synapses(post_id=neuron_id)
 
         assert (synapses[:, 1] == neuron_id).all(), "!!!! Wrong synapses extracted"
 
         neurons = dict([])
 
         post_neuron = self.network_load.load_neuron(neuron_id)
-        axis = post_neuron.plot_neuron(axis=axis, plot_axon=False,
-                                       plot_dendrite=True)
+        axis = post_neuron.plot_neuron(axis=axis, plot_axon=False, plot_dendrite=True)
 
         plotted_neurons = [neuron_id]
 
@@ -1770,14 +1677,11 @@ def plot_neurons(self, neuron_id, show_synapses=True, plot_pre_neurons=True):
 
                 if src_id not in plotted_neurons:
                     neurons[src_id] = self.network_load.load_neuron(src_id)
-                    axis = neurons[src_id].plot_neuron(axis=axis, plot_axon=True,
-                                                       plot_dendrite=False)
+                    axis = neurons[src_id].plot_neuron(axis=axis, plot_axon=True, plot_dendrite=False)
                     plotted_neurons.append(src_id)
 
         if show_synapses:
-            axis.scatter(synapse_coords[:, 0],
-                         synapse_coords[:, 1],
-                         synapse_coords[:, 2], c='red')
+            axis.scatter(synapse_coords[:, 0], synapse_coords[:, 1], synapse_coords[:, 2], c='red')
 
         plt.ion()
         plt.draw()
@@ -1791,20 +1695,6 @@ def plot_neurons(self, neuron_id, show_synapses=True, plot_pre_neurons=True):
 
     ############################################################################
 
-    def find_latest_file(self):
-
-        files = glob('save/network-connect-voxel-pruned-synapse-file-*.hdf5')
-        #    files = glob('save/network-connect-synapse-file-*.hdf5')
-
-        mod_time = [os.path.getmtime(f) for f in files]
-        idx = np.argsort(mod_time)
-
-        print("Using the newest file: " + files[idx[-1]])
-
-        return files[idx[-1]]
-
-    ############################################################################
-
     # Loop through all synapses, create distance histogram
 
     def synapse_dist(self, side_len=None, volume_id="Striatum"):
@@ -1852,7 +1742,7 @@ def synapse_dist(self, side_len=None, volume_id="Striatum"):
             syn_increment = 8  # Becaues we use 1/8th of volume,
             # count all synapses 8 times
         else:
-            print("Unknown volume type: " + str(self.volume_type))
+            print(f"Unknown volume type: {self.volume_type}")
             import pdb
             pdb.set_trace()
 
@@ -1865,20 +1755,19 @@ def synapse_dist(self, side_len=None, volume_id="Striatum"):
         # otherwise we use too much memory.
         while start_idx < n_synapses:
 
-            assert start_idx <= end_idx, "startIdx = " + str(start_idx) + ", endIdx = " + str(end_idx)
+            assert start_idx <= end_idx, f"startIdx = {start_idx}, endIdx = {end_idx}"
 
             all_pre_id = self.data["network"]["synapses"][start_idx:end_idx, 0]
             all_post_id = self.data["network"]["synapses"][start_idx:end_idx, 1]
 
             # Dist to soma on dendrite
-            all_dist_idx = np.array(np.floor(self.data["network"]["synapses"][start_idx:end_idx, 8]
-                                             * bin_scaling),
+            all_dist_idx = np.array(np.floor(self.data["network"]["synapses"][start_idx:end_idx, 8] * bin_scaling),
                                     dtype=np.int)
 
             last_pre = None
             last_post = None
 
-            print("nSynapses = " + str(n_synapses) + ", at " + str(start_idx))
+            print(f"n_synapses = {n_synapses}, at {start_idx}")
 
             for i in range(0, all_pre_id.shape[0]):
 
@@ -1904,7 +1793,7 @@ def synapse_dist(self, side_len=None, volume_id="Striatum"):
 
         t_b = timeit.default_timer()
 
-        print("Created distance histogram (optimised) in " + str(t_b - t_a) + " seconds")
+        print(f"Created distance histogram (optimised) in {t_b - t_a} seconds")
 
     ############################################################################
 
@@ -1957,9 +1846,9 @@ def plot_synapse_cum_dist_summary(self, pair_list):
                          cum_dist[:end_idx],
                          linewidth=line_width, color=plot_col)
 
-                fig_name += "_" + pre_type + "-" + post_type
+                fig_name += f"_{pre_type}-{post_type}"
 
-                legend_text.append(self.neuron_name(pre_type) + "-" + self.neuron_name(post_type))
+                legend_text.append(f"{self.neuron_name(pre_type)}-{self.neuron_name(post_type)}")
 
             except:
                 import traceback
@@ -1997,9 +1886,8 @@ def plot_synapse_cum_dist(self):
             cum_dist = np.cumsum(self.dend_position_bin[pair]) / np.sum(self.dend_position_bin[pair])
 
             idx = np.where(cum_dist < 0.5)[0][-1]
-            print(self.all_types[pair[0]] + " to " + self.all_types[pair[1]]
-                  + " 50% of synapses are within "
-                  + str(self.dend_position_edges[idx] * 1e6) + " micrometer")
+            print(f"{self.all_types[pair[0]]} to {self.all_types[pair[1]]} 50% of synapses are within "
+                  f"{self.dend_position_edges[idx] * 1e6} micrometer")
 
             # Dont plot the full range
             end_idx = np.where(self.dend_position_edges <= 300e-6)[0][-1]
@@ -2016,8 +1904,8 @@ def plot_synapse_cum_dist(self):
                          linewidth=3)
                 plt.xlabel('Distance from soma ($\mu$m)')
                 plt.ylabel('Cumulative distrib.')
-                plt.title('Synapses ' + self.neuron_name(self.all_types[pre_type])
-                          + " to " + self.neuron_name(self.all_types[post_type]))
+                plt.title(f"Synapses {self.neuron_name(self.all_types[pre_type])} "
+                          f"to {self.neuron_name(self.all_types[post_type])}")
                 plt.tight_layout()
 
                 plt.ion()
@@ -2027,9 +1915,8 @@ def plot_synapse_cum_dist(self):
 
                 plt.draw()
                 plt.pause(0.0001)
-                fig_name = "SynapseCumulativeDistribution-" \
-                           + self.neuron_name(self.all_types[pre_type]) + "-to-" \
-                           + self.neuron_name(self.all_types[post_type])
+                fig_name = (f"SynapseCumulativeDistribution-{self.neuron_name(self.all_types[pre_type])}"
+                            f"-to-{self.neuron_name(self.all_types[post_type])}")
 
                 self.save_figure(plt, fig_name)
 
@@ -2049,15 +1936,10 @@ def plot_synapse_dist(self, density_flag=False, side_len=None):
         if side_len is None:
             side_len = self.side_len
 
-        # import pdb
-        # pdb.set_trace()
-
         dend_hist_tot = self.dendrite_density(num_bins=len(self.dend_position_edges),
                                               bin_width=self.dend_position_edges[1],
                                               side_len=side_len)
 
-        # self.dendPositionBin calculated by synapseDist(), done at time of init
-
         for pair in self.dend_position_bin:
 
             if sum(self.dend_position_bin[pair]) == 0:
@@ -2094,8 +1976,7 @@ def plot_synapse_dist(self, density_flag=False, side_len=None):
                     plt.xlabel('Distance from soma ($\mu$m)')
                     plt.ylim([0, np.ceil(np.max(self.dend_position_bin[pair][:end_idx]))])
 
-                    plt.title('Synapses ' + self.neuron_name(pre_type)
-                              + " to " + self.neuron_name(post_type))
+                    plt.title(f"Synapses {self.neuron_name(pre_type)} to {self.neuron_name(post_type)}")
 
                 plt.tight_layout()
 
@@ -2105,11 +1986,9 @@ def plot_synapse_dist(self, density_flag=False, side_len=None):
                 plt.pause(0.0001)
 
                 if density_flag:
-                    fig_name = "SynapseDistribution-density-dend-" \
-                              + pre_type + "-to-" + post_type
+                    fig_name = f"SynapseDistribution-density-dend-{pre_type}-to-{post_type}"
                 else:
-                    fig_name = "SynapseDistribution-dend-" \
-                              + pre_type + "-to-" + post_type
+                    fig_name = f"SynapseDistribution-dend-{pre_type}-to-{post_type}"
 
                 self.save_figure(plt, fig_name)
 
@@ -2139,18 +2018,18 @@ def dendrite_density(self, num_bins, bin_width, side_len=None, volume_id="Striat
         if side_len is None:
             side_len = self.side_len
 
-        print("Using nBins = " + str(num_bins) + ", binWidth = " + str(bin_width))
+        print(f"Using num_bins = {num_bins}, bin_width = {bin_width}")
 
         # 1. Loop through all morphologies
         morph_files = set([self.data["morphologies"][name]["location"][()]
-                          for name in self.data["morphologies"]])
+                           for name in self.data["morphologies"]])
 
         morph_hist = dict([])
         for m_file in morph_files:
             morph_hist[m_file] = self._dend_density(m_file, num_bins, bin_width)
 
         neuron_types = set([m.split("_")[0]
-                           for m in self.data["morphologies"]])
+                            for m in self.data["morphologies"]])
 
         # 2. Sum all the histograms together, with the right multiplicity
 
@@ -2197,7 +2076,7 @@ def _dend_density(self, swc_file, num_bins, bin_width):
 
         n_morph = NeuronMorphology(swc_filename=swc_file)
 
-        print("Parsing dendrite histogram : " + swc_file)
+        print(f"Parsing dendrite histogram : {swc_file}")
 
         # 0,1,2: x,y,z  3: radie, 4: dist to soma
         dist_to_soma = n_morph.dend[:, 4]
@@ -2255,16 +2134,15 @@ def virtual_axon_synapses(self, post_neuron_type):
             plt.hist(v_syn, bins=virt_syn_bins, align="left")
             plt.xlabel("Synapses (only connected pairs)")
             plt.ylabel("Count")
-            plt.title("Synapses from " + self.neuron_name(axonType)
-                      + " to " + self.neuron_name(post_neuron_type)
-                      + " (nSyn=" + str(np.sum(v_syn)) + ")")
+            plt.title(f"Synapses from {self.neuron_name(axonType)} "
+                      f"to {self.neuron_name(post_neuron_type)} (num_syn={np.sum(v_syn)})")
 
             plt.tight_layout()
 
             plt.ion()
             plt.draw()
 
-            fig_name = "VirtuaAxon-synapses-" + axonType + "-to-" + post_neuron_type
+            fig_name = f"VirtuaAxon-synapses-{axonType}-to-{post_neuron_type}"
 
             self.save_figure(plt, fig_name)
 
@@ -2278,8 +2156,7 @@ def virtual_axon_synapses(self, post_neuron_type):
 
     def count_motifs(self, type_a, type_b, type_c, n_repeats=1000000):
 
-        print("Counting motivs between " + str(type_a) + ", " + str(type_b) \
-              + " " + str(type_c) + ". " + str(n_repeats) + " repeats.")
+        print(f"Counting motivs between {type_a}, {type_b} {type_c}. {n_repeats} repeats.")
 
         ida = self.populations[type_a]
         idb = self.populations[type_b]
@@ -2303,7 +2180,7 @@ def count_motifs(self, type_a, type_b, type_c, n_repeats=1000000):
         for i_rep in range(0, n_repeats):
 
             if i_rep % 100000 == 0 and i_rep > 0:
-                print("rep: " + str(i_rep))
+                print(f"rep: {i_rep}")
 
             i_a = i_a_all[i_rep]
             i_b = i_b_all[i_rep]
@@ -2335,9 +2212,6 @@ def analyse_single_motifs(self, neuron_type, num_repeats=10000000):
                                                     type_c=neuron_type,
                                                     n_repeats=num_repeats)
 
-        # !!! For debug
-        # motifCtr = [bin(x).count('1') for x in np.arange(0,64)]
-
         # No connections
         no_con = motif_ctr[0]
 
@@ -2392,7 +2266,7 @@ def analyse_single_motifs(self, neuron_type, num_repeats=10000000):
                     ("Three connections, circular, one flipped", three_circle_flip),
                     ("Three connections, one bidirectional, one away", three_bi_div),
                     ("Three connections, one bidirectional, one towards",
-                    three_bi_conv),
+                     three_bi_conv),
                     ("Four connections, two bidirectional", four_double_bi),
                     ("Four connections, one bi, two away", four_bi_diverge),
                     ("Four connections, one bi, two towards", four_bi_converge),
@@ -2402,7 +2276,7 @@ def analyse_single_motifs(self, neuron_type, num_repeats=10000000):
 
         print("Motif analysis:")
         for (name, data) in con_data:
-            print(name + " " + str(100 * data / num_repeats) + "% (" + str(data) + ")")
+            print(f"{name} {100 * data / num_repeats}% ({data})")
 
     ############################################################################
 
@@ -2440,7 +2314,7 @@ def simple_motif(self, type_a, type_b, type_c, n_rep=1000):
             ctr_a += 1
 
             if ctr_a % 100 == 0:
-                print(str(ctr_a) + "/" + str(n_a))
+                print(f"{ctr_a}/{n_a}")
 
             mat_row = self.connection_matrix[iA, :]
 
@@ -2462,11 +2336,10 @@ def simple_motif(self, type_a, type_b, type_c, n_rep=1000):
 
                     all_ctr += 1
 
-        print("If " + str(type_a) + " connected to " + str(type_b) + " " \
-              + str(type_c) + ":")
-        print("P(" + type_b + "->" + type_c + ") = " + str((100.0 * con_bc) / all_ctr) + "%")
-        print("P(" + type_c + "->" + type_b + ") = " + str((100.0 * con_cb) / all_ctr) + "%")
-        print("P(" + type_b + "<->" + type_c + ") = " + str((100.0 * con_bi) / all_ctr) + "%")
+        print(f"If {type_a} connected to {type_b} {type_c}:")
+        print(f"P({type_b} --> {type_c}) = {(100.0 * con_bc) / all_ctr}%")
+        print(f"P({type_c} --> {type_b}) = {(100.0 * con_cb) / all_ctr}%")
+        print(f"P({type_b} <-> {type_c}) = {(100.0 * con_bi) / all_ctr}%")
 
         return con_bc, con_cb, con_bi, all_ctr
 
@@ -2479,13 +2352,11 @@ def nearest_pre_neighbour_distance(self, pre_type, post_type, rabies_rate=1.0,
                                        name_str=""):
 
         if pre_type not in self.populations:
-            print("nearestPreNeighbourDistance: " + str(pre_type)
-                  + " is not in the simulation")
+            print(f"nearest_pre_neighbour_distance: {pre_type} is not in the simulation")
             return
 
         if post_type not in self.populations:
-            print("nearestPreNeighbourDistance: " + str(post_type)
-                  + " is not in the simulation")
+            print(f"nearest_pre_neighbour_distance: {post_type} is not in the simulation")
             return
 
         # postPop = self.getSubPop(neuronID=self.populations[postType],
@@ -2502,7 +2373,7 @@ def nearest_pre_neighbour_distance(self, pre_type, post_type, rabies_rate=1.0,
         slice_max_z = (max_z + min_z) / 2 + 150e-6
 
         slice_pop = np.where(np.bitwise_and(slice_min_z <= self.positions[:, 2],
-                                           self.positions[:, 2] <= slice_max_z))[0]
+                                            self.positions[:, 2] <= slice_max_z))[0]
 
         # Only look at neurons in slice
         pre_pop = np.intersect1d(pre_pop, slice_pop)
@@ -2522,9 +2393,7 @@ def nearest_pre_neighbour_distance(self, pre_type, post_type, rabies_rate=1.0,
                 keep_idx = np.where(np.random.rand(len(con_idx)) < rabies_rate)[0]
                 con_idx = con_idx[keep_idx]
 
-            d = np.sqrt(np.sum((self.positions[con_idx, :3]
-                                - self.positions[postID, :3]) ** 2,
-                               axis=1))
+            d = np.sqrt(np.sum((self.positions[con_idx, :3] - self.positions[postID, :3]) ** 2, axis=1))
 
             if len(d) > 0:
                 nearest_dist[c] = np.min(d) * 1e6  # micrometers
@@ -2538,24 +2407,24 @@ def nearest_pre_neighbour_distance(self, pre_type, post_type, rabies_rate=1.0,
 
         plt.xlabel("Distance")
         if rabies_rate is not None and rabies_rate < 1:
-            plt.ylabel("Count (Rabies rate: " + str(rabies_rate * 100) + "%)")
+            plt.ylabel(f"Count (Rabies rate: {rabies_rate * 100}%)")
         else:
             plt.ylabel("Count")
-        plt.title("Nearest presynaptic neighbour "
-                  + self.neuron_name(pre_type) + " to " + self.neuron_name(post_type))
+
+        plt.title(f"Nearest presynaptic neighbour {self.neuron_name(pre_type)} to {self.neuron_name(post_type)}")
 
         # Data from Sabatini 2016
         if pre_type == "LTS" and (post_type == "dSPN" or post_type == "iSPN"):
-            sabatini_lts = np.genfromtxt("DATA/LTS-nearest-neighbour-points-Sabatini2016.csv", delimiter=",")
+            sabatini_lts = np.genfromtxt(os.path.join("DATA", "LTS-nearest-neighbour-points-Sabatini2016.csv"),
+                                         delimiter=",")
             lts_points = sabatini_lts[:, 1] * 1e3  # Get in micrometer
             plt.hist(lts_points, color='r', histtype="step")
 
         plt.ion()
         plt.draw()
 
-        fig_name = "Nearest-presynaptic-slice-neighbour-to-" \
-                  + str(post_type) + "-from-" + str(pre_type) + "-ID-" \
-                  + str(self.network["SlurmID"]) + name_str + ".pdf"
+        fig_name = (f"Nearest-presynaptic-slice-neighbour-to-{post_type}-from-{pre_type}"
+                    f"-ID-{self.network['SlurmID']}{name_str}.pdf")
 
         self.save_figure(plt, fig_name)
 
@@ -2616,20 +2485,19 @@ def nearest_pre_neighbour_distance_old(self, pre_type, post_type, num_max=1000,
 
         plt.xlabel("Distance")
         plt.ylabel("Count")
-        plt.title("Nearest presynaptic neighbour "
-                  + self.neuron_name(pre_type) + " to " + self.neuron_name(post_type))
+        plt.title(f"Nearest presynaptic neighbour {self.neuron_name(pre_type)} to {self.neuron_name(post_type)}")
 
         # Data from Sabatini 2016
         if pre_type == "LTS" and (post_type == "dSPN" or post_type == "iSPN"):
-            sabatini_lts = np.genfromtxt("../DATA/LTS-nearest-neighbour-points-Sabatini2016.csv", delimiter=",")
+            sabatini_lts = np.genfromtxt(os.path.join("..", "DATA", "LTS-nearest-neighbour-points-Sabatini2016.csv"),
+                                         delimiter=",")
             lts_points = sabatini_lts[:, 1] * 1e3  # Get in micrometer
             plt.hist(lts_points, color='r', histtype="step")
 
         plt.ion()
         plt.draw()
 
-        fig_name = "figures/Nearest-presynaptic-neighbour-to-" \
-                   + str(post_type) + "-from-" + str(pre_type)
+        fig_name = os.path.join("figures", f"Nearest-presynaptic-neighbour-to-{post_type}-from-{pre_type}")
 
         self.save_figure(plt, fig_name)
 
@@ -2657,7 +2525,7 @@ def chuhma_virtual_experiment(self, tagged_type=["dSPN", "iSPN"], tag_fraction=0
 
         # Find all presynaptic neurons
         pre_idx = np.where(np.sum(self.connection_matrix[:, tagged_neurons],
-                                 axis=1) > 0)[0]
+                                  axis=1) > 0)[0]
 
         # Ooops, no fun... pretty much all neurons got tagged.
 
@@ -2677,7 +2545,7 @@ def chuhma_virtual_experiment(self, tagged_type=["dSPN", "iSPN"], tag_fraction=0
 
     if len(sys.argv) > 1:
         hdf5File = sys.argv[1]
-        print("Using user supplied HDF5 file: " + hdf5File)
+        print(f"Using user supplied HDF5 file: {hdf5File}")
 
     else:
         hdf5File = None  # Auto detect, use latest file
@@ -2920,4 +2788,3 @@ def chuhma_virtual_experiment(self, tagged_type=["dSPN", "iSPN"], tag_fraction=0
     print("All done, exiting")
     # import pdb
     # pdb.set_trace()
-
diff --git a/snudda/analyse/analyse_neuroinformatics2020.py b/snudda/analyse/analyse_neuroinformatics2020.py
index 4636c8a00..d1ccb53c2 100644
--- a/snudda/analyse/analyse_neuroinformatics2020.py
+++ b/snudda/analyse/analyse_neuroinformatics2020.py
@@ -4,11 +4,11 @@
 #
 #
 
-import numpy as np
-import sys
 import os
+import sys
 
 import matplotlib.pyplot as plt
+import numpy as np
 
 from snudda.analyse.analyse import SnuddaAnalyse
 
@@ -23,15 +23,15 @@ def __init__(self, sim_dir, volume_type="cube", side_len=300e-6):
             self.simDir = os.path.dirname(sim_dir)
         else:
             self.simDir = sim_dir
-            hdf5_file = sim_dir + "/network-synapses.hdf5"
+            hdf5_file = os.path.join(sim_dir, "network-synapses.hdf5")
 
             if not os.path.exists(hdf5_file):
-                alt_hdf5_file = sim_dir + "/network-connect-voxel-pruned-synapse-file.hdf5"
+                alt_hdf5_file = os.path.join(sim_dir, "network-connect-voxel-pruned-synapse-file.hdf5")
 
                 if os.path.exists(alt_hdf5_file):
                     hfd5_file = alt_hdf5_file
 
-        print("Loading " + str(hdf5_file))
+        print(f"Loading {hdf5_file}")
 
         super().__init__(hdf5_file=hdf5_file, load_cache=True,
                          volume_type=volume_type,
@@ -132,7 +132,7 @@ def plot_fs_lts_cum_dist(self, plot_fs=True, plot_lts=True):
 
     if len(sys.argv) > 1:
         sim_dir = sys.argv[1]
-        print("Reading network from " + str(sim_dir))
+        print(f"Reading network from {sim_dir}")
     else:
         print("Please specify which directory the striatum network files is in")
         sys.exit(-1)
diff --git a/snudda/analyse/analyse_striatum.py b/snudda/analyse/analyse_striatum.py
index cbfa934dd..0a8227ade 100644
--- a/snudda/analyse/analyse_striatum.py
+++ b/snudda/analyse/analyse_striatum.py
@@ -4,11 +4,11 @@
 #
 #
 
-import numpy as np
-import sys
 import os
+import sys
 
 import matplotlib.pyplot as plt
+import numpy as np
 
 from snudda.analyse.analyse import SnuddaAnalyse
 
@@ -168,21 +168,21 @@ def plot_fslt_scum_dist(self, plot_fs=True, plot_lts=True):
     if plotHenrike:
         yMaxH = None  # 0.5
 
-        nas.plot_connection_probability("dSPN", "iSPN", 
-                                        dist_3d=dist3D, 
-                                        exp_max_dist=[50e-6, 100e-6], 
+        nas.plot_connection_probability("dSPN", "iSPN",
+                                        dist_3d=dist3D,
+                                        exp_max_dist=[50e-6, 100e-6],
                                         exp_data=[3 / 47.0, 3 / 66.0],
                                         exp_data_detailed=[(3, 47), (3, 66)],
                                         y_max=yMaxH)
-        nas.plot_connection_probability("dSPN", "dSPN", 
-                                        dist_3d=dist3D, 
-                                        exp_max_dist=[50e-6, 100e-6], 
+        nas.plot_connection_probability("dSPN", "dSPN",
+                                        dist_3d=dist3D,
+                                        exp_max_dist=[50e-6, 100e-6],
                                         exp_data=[5 / 19.0, 3 / 43.0],
                                         exp_data_detailed=[(5, 19), (3, 43)],
                                         y_max=yMaxH)
-        nas.plot_connection_probability("iSPN", "dSPN", 
-                                        dist_3d=dist3D, 
-                                        exp_max_dist=[50e-6, 100e-6], 
+        nas.plot_connection_probability("iSPN", "dSPN",
+                                        dist_3d=dist3D,
+                                        exp_max_dist=[50e-6, 100e-6],
                                         exp_data=[13 / 47.0, 10 / 80.0],
                                         exp_data_detailed=[(13, 47), (10, 80)],
                                         y_max=yMaxH)
diff --git a/snudda/detect/detect.py b/snudda/detect/detect.py
index 461b7026e..501b9930a 100644
--- a/snudda/detect/detect.py
+++ b/snudda/detect/detect.py
@@ -11,36 +11,28 @@
 # Grant Agreements No. 720270 and No. 785907 (Human Brain Project SGA1
 # and SGA2).
 #
-from collections import OrderedDict
-
-import numexpr
-import numpy as np
+import itertools
+import json
 import os
 import sys
-import itertools
-
 import time
 import timeit
+from collections import OrderedDict
 
 import h5py
-import json
-import pickle
-
+import numexpr
+import numpy as np
 from numba import jit
 
+import snudda.utils.memory
 from snudda.detect.projection_detection import ProjectionDetection
-from snudda.neurons.neuron_morphology import NeuronMorphology
 from snudda.neurons.neuron_prototype import NeuronPrototype
-
 from snudda.utils.load import SnuddaLoad
 
-import snudda.utils.memory
-
 
 # TODO: Exclude neurons without synapses or gap junctions from touch detection (ie if no pre/post connections possible)
 
 class SnuddaDetect(object):
-
     """
     SnuddaDetect places synapses in the network based on touch detection.
     """
@@ -61,6 +53,7 @@ def __init__(self,
                  role=None,  # Default: "master"
                  rc=None,
                  axon_stump_id_flag=False,
+                 simulation_origo = None,  # Auto detect
                  h5libver=None,  # Default: "latest"
                  random_seed=None,
                  debug_flag=False):
@@ -84,6 +77,7 @@ def __init__(self,
             role (str, optional): Parallel role, i.e. "master" or "worker"
             rc (ipyparallel.Client, optional): iPyParallel client, if given program will run in parallel
             axon_stump_id_flag (bool, optional): Recalculate segment IDs to account for axon stump? (default False)
+            simulation_origo (np.array, optional): Origo for touch detection hypervoxels and voxels, voxel coordinates must always positive.
             h5libver (string, optional): h5py library version (default "latest")
             random_seed (int, optional): Random seed
             debug_flag (bool, optional): Save additional information for debugging (Default: False)
@@ -201,7 +195,7 @@ def __init__(self,
         self.hyper_voxel_id_lookup = None
         self.num_hyper_voxels = None
         self.hyper_voxel_width = self.hyper_voxel_size * self.voxel_size
-        self.simulation_origo = None
+        self.simulation_origo = np.array(simulation_origo) if simulation_origo is not None else None
 
         self.config = None
 
@@ -411,7 +405,7 @@ def parallel_process_hyper_voxels(self, rc=None, d_view=None):
 
                 # We have an async result, check status of it
                 if worker_status[worker_idx].ready():
-                    
+
                     # Result is ready, get it
                     hyper_voxel_data = rc[worker_idx]["result"]
 
@@ -437,8 +431,8 @@ def parallel_process_hyper_voxels(self, rc=None, d_view=None):
                     else:
                         if exec_time > 100 or self.verbose:
                             # Only print the long running hyper voxels
-                            self.write_log(f"HyperID {hyper_id} completed " 
-                                           f"- {num_syn} synapses found ({np.around(exec_time,1)} s)",
+                            self.write_log(f"HyperID {hyper_id} completed "
+                                           f"- {num_syn} synapses found ({np.around(exec_time, 1)} s)",
                                            force_print=True)
                         elif not info_msg_written:
                             self.write_log(f"Suppressing printouts for hyper voxels that complete in < 100 seconds.",
@@ -474,7 +468,7 @@ def parallel_process_hyper_voxels(self, rc=None, d_view=None):
 
         end_time = timeit.default_timer()
 
-        self.write_log(f"Voxel overflows: {self.voxel_overflow_counter}", is_error=(self.voxel_overflow_counter>0))
+        self.write_log(f"Voxel overflows: {self.voxel_overflow_counter}", is_error=(self.voxel_overflow_counter > 0))
         self.write_log(f"Total number of synapses: {np.sum(self.work_history['nHypervoxelSynapses'][:])}")
         self.write_log(f"parallelProcessHyperVoxels: {end_time - start_time:.1f} s")
 
@@ -1147,12 +1141,11 @@ def detect_synapses(self):
                                 cluster_param_id = self.hyper_voxel_rng.integers(1000000, size=cluster_size)
 
                                 # We need to convert coords to hyper voxel coords, to fit with other coords
-                                coords_all = np.round((syn_coords - self.hyper_voxel_origo) / self.voxel_size).astype(int)
+                                coords_all = np.round((syn_coords - self.hyper_voxel_origo)/self.voxel_size).astype(int)
 
                                 for d_sec_x, x, y, z, d_dist, cond, param_id \
-                                    in zip(cluster_sec_x, coords_all[:, 0], coords_all[:, 1], coords_all[:, 2],
-                                           soma_dist, cluster_cond, cluster_param_id):
-
+                                        in zip(cluster_sec_x, coords_all[:, 0], coords_all[:, 1], coords_all[:, 2],
+                                               soma_dist, cluster_cond, cluster_param_id):
                                     assert cond > 0, f"Conductance should be larger than 0. cond = {cond}"
 
                                     self.hyper_voxel_synapses[self.hyper_voxel_synapse_ctr, :] = \
@@ -1335,7 +1328,7 @@ def place_synapses_no_axon(self, hyper_id, voxel_space, voxel_space_ctr,
 
                 (na_voxel_coords, na_axon_dist) = self.no_axon_points_xyz(na_neuron["position"],
                                                                           na_neuron["rotation"],
-                                                                          na_neuron["axonDensity"],  # axon_density_func,
+                                                                          na_neuron["axonDensity"],
                                                                           na_neuron["axonDensityBoundsXYZ"])
             else:
                 self.write_log(f"Unknown axonDensityType: {na_neuron['axonDensityType']}\n{na_neuron}", is_error=True)
@@ -1539,7 +1532,7 @@ def no_axon_points_xyz(self, neuron_position, rotation,
                            / np.sum(density_inside / max_density)).astype(int)
 
         if n_tries > 1e6:
-            self.write_log(f"!!! noAxonPointsXYZ: Warning trying to place {n_tries} points. " 
+            self.write_log(f"!!! noAxonPointsXYZ: Warning trying to place {n_tries} points. "
                            "Bounds: {axon_density_bounds_xyz}")
 
         # Only print this in verbose mode
@@ -1616,7 +1609,7 @@ def sort_synapses(self):
         """
 
         sort_idx = np.lexsort(self.hyper_voxel_synapses[:self.hyper_voxel_synapse_ctr,
-                              [6, 0, 1]].transpose())   # Sort order: columns 1 (dest), 0 (src), 6 (synapse type)
+                              [6, 0, 1]].transpose())  # Sort order: columns 1 (dest), 0 (src), 6 (synapse type)
 
         self.hyper_voxel_synapses[:self.hyper_voxel_synapse_ctr, :] = \
             self.hyper_voxel_synapses[sort_idx, :]
@@ -1682,7 +1675,7 @@ def create_lookup_table(data, n_rows, data_type, num_neurons, max_synapse_type):
         if data_type == "synapses":
             hardcoded_synapse_type = None
         elif data_type == "gap_junctions":
-            hardcoded_synapse_type = 3      # Hardcoded for gap junctions
+            hardcoded_synapse_type = 3  # Hardcoded for gap junctions
         else:
             assert False, f"Unknown data_type {data_type}, should be 'synapses' or ' gap_junctions'"
 
@@ -1691,7 +1684,7 @@ def create_lookup_table(data, n_rows, data_type, num_neurons, max_synapse_type):
         while next_idx < n_rows:
             src_id = data[next_idx, 0]
             dest_id = data[next_idx, 1]
-            
+
             if hardcoded_synapse_type:
                 synapse_type = hardcoded_synapse_type
             else:
@@ -1704,7 +1697,7 @@ def create_lookup_table(data, n_rows, data_type, num_neurons, max_synapse_type):
                    and data[next_idx, 1] == dest_id):
                 next_idx += 1
 
-            lookup_table[lookup_idx, :] = [(dest_id * num_neurons + src_id)*max_synapse_type + synapse_type,
+            lookup_table[lookup_idx, :] = [(dest_id * num_neurons + src_id) * max_synapse_type + synapse_type,
                                            start_idx, next_idx]
 
             start_idx = next_idx
@@ -1778,7 +1771,7 @@ def detect_gap_junctions(self):
 
                         # !!! Currently not using channelParamDict for GJ
 
-                        #gj_cond = self.hyper_voxel_rng.normal(mean_gj_cond, std_gj_cond)
+                        # gj_cond = self.hyper_voxel_rng.normal(mean_gj_cond, std_gj_cond)
                         # lognormal distribution https://www.nature.com/articles/nrn3687
                         gj_cond = self.hyper_voxel_rng.lognormal(gj_mu, gj_sigma)
 
@@ -2243,7 +2236,7 @@ def distribute_neurons_parallel(self, d_view=None):
 
         # Split the neuronIdx between the workers
         d_view.scatter("neuron_idx", neuron_idx, block=True)
-        d_view.scatter("distribution_seeds", distribution_seeds[neuron_idx], block=True) # Need to preserve order
+        d_view.scatter("distribution_seeds", distribution_seeds[neuron_idx], block=True)  # Need to preserve order
         d_view.push({"min_coord": min_coord,
                      "max_coord": max_coord}, block=True)
 
@@ -2350,7 +2343,12 @@ def distribute_neurons(self, neuron_idx=None, distribution_seeds=None, min_coord
                 (min_coord, max_coord) = self.find_min_max_coord()
 
             # Simulation origo is in meters
-            self.simulation_origo = min_coord
+            if self.simulation_origo is None:
+                self.simulation_origo = min_coord
+            else:
+                assert (self.simulation_origo <= min_coord).all(), \
+                    ( f"Simulation origo ({self.simulation_origo}) must be smaller than {min_coord}. "
+                      f"This since all voxel and hyper voxel coordinates must be positive." )
 
             assert ((self.num_bins - self.num_bins[0]) == 0).all(), "Hyper voxels should be cubes"
 
@@ -2399,13 +2397,13 @@ def distribute_neurons(self, neuron_idx=None, distribution_seeds=None, min_coord
                 neuron_id = n["neuronID"]
 
                 if neuron.dend.shape[0] > 0:
-                    dend_loc = np.floor((neuron.dend[:, :3] - self.simulation_origo) / self.hyper_voxel_width).astype(int)
+                    dend_loc = np.floor((neuron.dend[:, :3] - self.simulation_origo)/self.hyper_voxel_width).astype(int)
                 else:
                     dend_loc = np.zeros((0, 3))
 
                 if neuron.axon.shape[0] > 0:
                     # We have an axon, use it
-                    axon_loc = np.floor((neuron.axon[:, :3] - self.simulation_origo) / self.hyper_voxel_width).astype(int)
+                    axon_loc = np.floor((neuron.axon[:, :3] - self.simulation_origo)/self.hyper_voxel_width).astype(int)
 
                 elif neuron.axon_density_type == "r":
 
@@ -2440,7 +2438,7 @@ def distribute_neurons(self, neuron_idx=None, distribution_seeds=None, min_coord
                     axon_cloud[:, 1] = y + neuron.soma[0, 1]
                     axon_cloud[:, 2] = z + neuron.soma[0, 2]
 
-                    axon_loc = np.floor((axon_cloud[:, :3] - self.simulation_origo) / self.hyper_voxel_width).astype(int)
+                    axon_loc = np.floor((axon_cloud[:, :3] - self.simulation_origo)/self.hyper_voxel_width).astype(int)
 
                     axon_inside_flag = [0 <= xa < self.hyper_voxel_id_lookup.shape[0]
                                         and 0 <= ya < self.hyper_voxel_id_lookup.shape[1]
@@ -2481,7 +2479,7 @@ def distribute_neurons(self, neuron_idx=None, distribution_seeds=None, min_coord
                     axon_cloud = np.matmul(neuron.rotation,
                                            axon_cloud.transpose()).transpose() + neuron.position
 
-                    axon_loc = np.floor((axon_cloud[:, :3] - self.simulation_origo) / self.hyper_voxel_width).astype(int)
+                    axon_loc = np.floor((axon_cloud[:, :3] - self.simulation_origo)/self.hyper_voxel_width).astype(int)
 
                     axon_inside_flag = [0 <= x < self.hyper_voxel_id_lookup.shape[0]
                                         and 0 <= y < self.hyper_voxel_id_lookup.shape[1]
@@ -2591,8 +2589,8 @@ def setup_parallel(self, d_view=None):
 
         self.write_log("Init values pushed to workers")
 
-        cmd_str = ("sd = SnuddaDetect(config_file=config_file, position_file=position_file,voxel_size=voxel_size," 
-                   "hyper_voxel_size=hyper_voxel_size,verbose=verbose,logfile_name=logfile_name[0]," 
+        cmd_str = ("sd = SnuddaDetect(config_file=config_file, position_file=position_file,voxel_size=voxel_size,"
+                   "hyper_voxel_size=hyper_voxel_size,verbose=verbose,logfile_name=logfile_name[0],"
                    "save_file=save_file,slurm_id=slurm_id,role='worker', random_seed=random_seed)")
         d_view.execute(cmd_str, block=True)
 
@@ -2656,7 +2654,6 @@ def find_min_max_coord(self, volume_id=None, neuron_idx=None):
             min_coord, max_coord
         """
 
-
         try:
             if volume_id is None:
                 volume_id = self.volume_id
@@ -2746,8 +2743,8 @@ def fill_voxels_soma(self, voxel_space, voxel_space_ctr,
                 for vz in range(vz_min, vz_max):
 
                     d2 = (((vx + 0.5) * self.voxel_size + self.hyper_voxel_origo[0] - soma_coord[0, 0]) ** 2
-                         + ((vy + 0.5) * self.voxel_size + self.hyper_voxel_origo[1] - soma_coord[0, 1]) ** 2
-                         + ((vz + 0.5) * self.voxel_size + self.hyper_voxel_origo[2] - soma_coord[0, 2]) ** 2)
+                          + ((vy + 0.5) * self.voxel_size + self.hyper_voxel_origo[1] - soma_coord[0, 1]) ** 2
+                          + ((vz + 0.5) * self.voxel_size + self.hyper_voxel_origo[2] - soma_coord[0, 2]) ** 2)
 
                     if d2 < radius2:
                         # Mark the point
@@ -3226,7 +3223,6 @@ def process_hyper_voxel(self, hyper_id):
             # and then do axon-dend synapse touch detection
 
             for neuron_id in self.hyper_voxels[hyper_id]["neurons"][:num_neurons]:
-
                 neuron = self.load_neuron(self.neurons[neuron_id])
 
                 self.fill_voxels_axon(self.axon_voxels,
@@ -3358,13 +3354,13 @@ def plot_hyper_voxel(self, plot_neurons=False, draw_axons=True, draw_dendrites=T
             # to draw within the hyper voxel
             if self.hyper_voxel_offset is not None:
                 syn_coord -= self.hyper_voxel_offset
-            ax.scatter(syn_coord[:, 0]+0.5, syn_coord[:, 1]+0.5, syn_coord[:, 2]+0.5, c="green", s=64)
+            ax.scatter(syn_coord[:, 0] + 0.5, syn_coord[:, 1] + 0.5, syn_coord[:, 2] + 0.5, c="green", s=64)
 
         if self.hyper_voxel_gap_junction_ctr > 0:
             gj_coord = self.hyper_voxel_gap_junctions[:self.hyper_voxel_gap_junction_ctr, 6:9]
             if self.hyper_voxel_offset is not None:
                 gj_coord -= self.hyper_voxel_offset
-            ax.scatter(gj_coord[:, 0]+0.5, gj_coord[:, 1]+0.5, gj_coord[:, 2]+0.5, c="yellow", s=64)
+            ax.scatter(gj_coord[:, 0] + 0.5, gj_coord[:, 1] + 0.5, gj_coord[:, 2] + 0.5, c="yellow", s=64)
 
         if elev_azim:
             ax.view_init(elev_azim[0], elev_azim[1])
@@ -3404,7 +3400,7 @@ def plot_hyper_voxel(self, plot_neurons=False, draw_axons=True, draw_dendrites=T
             plt.title("Scale is in voxels, not micrometers")
         else:
             plt.title(title)
-            
+
         if fig_file_name is None:
             fig_file_name = f"Hypervoxel-{self.slurm_id}-{self.hyper_voxel_id}.png"
 
@@ -3465,7 +3461,7 @@ def export_voxel_visualisation_csv(self, neuron_id):
         for i in syn_list:
             xyz = self.hyper_voxel_synapses[i, 2:5]
             synapse_str += str(xyz[0]) + "," + str(xyz[1]) + "," + str(xyz[2]) \
-                         + ",sphere,synapse," + str(self.hyper_voxel_synapses[i, 1]) + "\n"
+                           + ",sphere,synapse," + str(self.hyper_voxel_synapses[i, 1]) + "\n"
 
         f_name = "hypervoxel-" + str(self.slurm_id) + ".csv"
         with open(f_name, 'w') as f:
@@ -3568,7 +3564,7 @@ def plot_neurons_in_hyper_voxel(self, neuron_id, neuron_colour,
         if not os.path.exists(os.path.dirname(fig_name)):
             os.mkdir(os.path.dirname(fig_name))
 
-        plt.savefig(fig_name, dpi=dpi)  #dpi = 900
+        plt.savefig(fig_name, dpi=dpi)  # dpi = 900
 
         if show_plot:
             plt.ion()
@@ -3650,4 +3646,3 @@ def memory():
 if __name__ == "__main__":
     print("Please do not call this file directly, use snudda.py")
     sys.exit(-1)
-
diff --git a/snudda/detect/project.py b/snudda/detect/project.py
index 2d517ae2f..ccd268127 100644
--- a/snudda/detect/project.py
+++ b/snudda/detect/project.py
@@ -1,23 +1,20 @@
 # In addition to adding synapses using touch detection we also want the ability to add connections
 # when we do not have an axon, for example over long range between structures, to connect them together.
 # This is what project.py is responsible for.
-from collections import OrderedDict
-
-import numpy as np
 import json
 import os
-import h5py
+from collections import OrderedDict
 
+import h5py
+import numpy as np
 from scipy.interpolate import griddata
 
 from snudda.detect.detect import SnuddaDetect
-from snudda.neurons.neuron_morphology import NeuronMorphology
 from snudda.neurons.neuron_prototype import NeuronPrototype
 from snudda.utils.load import SnuddaLoad
 
 
 class SnuddaProject(object):
-
     """ Adds projections between neurons, useful for connecting different regions with long range connections. """
 
     # TODO: Add support for log files!!
@@ -168,11 +165,11 @@ def connect_projection_helper(self, pre_neuron_type, post_neuron_type, connectio
 
             if "projectionName" in con_info:
                 proj_name = con_info["projectionName"]
-                projection_source = np.array(projection_data[proj_name]["source"])*1e-6
-                projection_destination = np.array(projection_data[proj_name]["destination"])*1e-6
+                projection_source = np.array(projection_data[proj_name]["source"]) * 1e-6
+                projection_destination = np.array(projection_data[proj_name]["destination"]) * 1e-6
             else:
-                projection_source = np.array(projection_data["source"])*1e-6
-                projection_destination = np.array(projection_data["destination"])*1e-6
+                projection_source = np.array(projection_data["source"]) * 1e-6
+                projection_destination = np.array(projection_data["destination"]) * 1e-6
 
             if "projectionRadius" in con_info:
                 projection_radius = con_info["projectionRadius"]
@@ -283,7 +280,7 @@ def connect_projection_helper(self, pre_neuron_type, post_neuron_type, connectio
                     sigma = np.sqrt(np.log(1 + conductance_std ** 2 / conductance_mean ** 2))
 
                     cond = self.rng.lognormal(mu, sigma, len(sec_x))
-                    cond = np.maximum(cond, conductance_mean*0.1)  # Lower bound, prevent negative.
+                    cond = np.maximum(cond, conductance_mean * 0.1)  # Lower bound, prevent negative.
                     param_id = self.rng.integers(1000000, size=len(sec_x))
 
                     # TODO: Add code to extend synapses matrix if it is full
@@ -293,7 +290,7 @@ def connect_projection_helper(self, pre_neuron_type, post_neuron_type, connectio
                              xyz[i, 0], xyz[i, 1], xyz[i, 2],
                              -1,  # Hypervoxelid
                              channel_model_id,
-                             ax_dist*1e6, dist_to_soma[i]*1e6,
+                             ax_dist * 1e6, dist_to_soma[i] * 1e6,
                              sec_id[i], sec_x[i] * 1000,
                              cond[i] * 1e12, param_id[i]]
                         self.synapse_ctr += 1
diff --git a/snudda/detect/projection_detection.py b/snudda/detect/projection_detection.py
index d1bebab82..4193b49e0 100644
--- a/snudda/detect/projection_detection.py
+++ b/snudda/detect/projection_detection.py
@@ -1,6 +1,7 @@
-import numpy as np
 import json
 from collections import OrderedDict
+
+import numpy as np
 from scipy.interpolate import griddata
 
 
@@ -260,7 +261,8 @@ def voxelise_projections(self):
                 pos = self.ellipsoid_coordinates(target_pos, rx, ry, rz, target_rotation, num_points, rng)
 
                 # Convert to coordinates in the hyper voxel
-                voxel_coords = np.round((pos - self.snudda_detect.hyper_voxel_origo) / self.snudda_detect.voxel_size).astype(int)
+                voxel_coords = np.round((pos - self.snudda_detect.hyper_voxel_origo)
+                                        / self.snudda_detect.voxel_size).astype(int)
 
                 inside_idx = np.where(np.sum(np.logical_and(0 <= voxel_coords,
                                                             voxel_coords < self.snudda_detect.hyper_voxel_size),
@@ -374,5 +376,3 @@ def add_projection(self, projection_name, pre_neuron_type, projection_file):
             self.projections[pre_neuron_type] = [proj_info]
         else:
             self.projections[pre_neuron_type].append(proj_info)
-
-
diff --git a/snudda/detect/prune.py b/snudda/detect/prune.py
index 5134e2a8f..d5f7cf5f8 100644
--- a/snudda/detect/prune.py
+++ b/snudda/detect/prune.py
@@ -20,26 +20,25 @@
 # sort ignoring all other neurons but their own
 # Finally, the resulting files from the workers are merged together
 
-import os
-import sys
-import numpy as np
-import scipy
-from numba import jit
-import math
-import numexpr
 import collections
-
+import glob
 import heapq  # Priority queue
-
+import json
+import math
+import os
+import sys
 import time
 import timeit
 
 import h5py
-import json
-import glob
+import numexpr
+import numpy as np
+import scipy
+from numba import jit
 
 from snudda.utils.numpy_encoder import NumpyEncoder
 
+
 # from snudda.Neuron_morphology import NeuronMorphology
 
 
@@ -52,11 +51,9 @@
 # !!! This also performs the pruning, since it requires knowledge of all
 #     synapses between the neurons, something not possible within a hyper voxel
 #     if the neuron crosses borders
-from snudda.utils.snudda_path import snudda_parse_path
 
 
 class SnuddaPrune(object):
-
     """ Prunes detected network synapses to match pairwise connectivity statistics. """
 
     ############################################################################
@@ -70,7 +67,7 @@ def __init__(self,
                  # pre_merge_only=False,
                  h5libver="latest",
                  random_seed=None,
-                 keep_files=False,   # If True then you can redo pruning multiple times without reruning detect
+                 keep_files=False,  # If True then you can redo pruning multiple times without reruning detect
                  all_neuron_pair_synapses_share_parameter_id=True):
 
         """
@@ -99,7 +96,7 @@ def __init__(self,
         self.rc = rc
         self.d_view = d_view
 
-        self.work_history_file = os.path.join(network_path, "log", "network-detect-worklog.hdf5")    
+        self.work_history_file = os.path.join(network_path, "log", "network-detect-worklog.hdf5")
         self.network_path = network_path
         self.keep_files = keep_files
         self.merge_info_file = os.path.join(self.network_path, "pruning_merge_info.json")
@@ -238,11 +235,11 @@ def prune(self):
         merge_info = self.get_merge_info()
         if merge_info:
             merge_files_syn, merge_neuron_range_syn, merge_syn_ctr, \
-                merge_files_gj, merge_neuron_range_gj, merge_gj_ctr = merge_info
+            merge_files_gj, merge_neuron_range_gj, merge_gj_ctr = merge_info
         else:
             # From the hyper voxels gather all synapses (and gap junctions) belonging to specific neurons
             merge_files_syn, merge_neuron_range_syn, merge_syn_ctr, \
-                merge_files_gj, merge_neuron_range_gj, merge_gj_ctr = self.gather_neuron_synapses()
+            merge_files_gj, merge_neuron_range_gj, merge_gj_ctr = self.gather_neuron_synapses()
 
             self.save_merge_info(merge_files_syn=merge_files_syn,
                                  merge_neuron_range_syn=merge_neuron_range_syn,
@@ -277,7 +274,6 @@ def prune(self):
         except:
             self.write_log("Problem closing out file - already closed?")
 
-
     ############################################################################
 
     def save_merge_info(self,
@@ -338,7 +334,7 @@ def get_merge_info_helper(self):
         merge_gj_ctr = data["merge_gj_ctr"]
 
         return merge_files_syn, merge_neuron_range_syn, merge_syn_ctr, \
-            merge_files_gj, merge_neuron_range_gj, merge_gj_ctr
+               merge_files_gj, merge_neuron_range_gj, merge_gj_ctr
 
     def get_merge_info(self):
 
@@ -361,7 +357,7 @@ def get_merge_info(self):
 
         try:
             merge_files_syn, merge_neuron_range_syn, merge_syn_ctr, \
-                merge_files_gj, merge_neuron_range_gj, merge_gj_ctr = self.get_merge_info_helper()
+            merge_files_gj, merge_neuron_range_gj, merge_gj_ctr = self.get_merge_info_helper()
         except:
             self.write_log(f"Problem readin merge info from {self.merge_info_file}")
             return None
@@ -390,7 +386,7 @@ def get_merge_info(self):
 
             with h5py.File(f_name, "r") as f:
                 if f["network/synapses"].shape[0] != syn_ctr:
-                    self.write_log(f"Bad merge info: {f_name} expected {syn_ctr} synapses, " 
+                    self.write_log(f"Bad merge info: {f_name} expected {syn_ctr} synapses, "
                                    f"found {f['network/synapses'].shape[0]}")
                     return None
 
@@ -411,7 +407,7 @@ def get_merge_info(self):
 
             with h5py.File(f_name, "r") as f:
                 if f["network/gapJunctions"].shape[0] != gj_ctr:
-                    self.write_log(f"Bad merge info: {f_name} expected {gj_ctr} gap junctions, " 
+                    self.write_log(f"Bad merge info: {f_name} expected {gj_ctr} gap junctions, "
                                    f"found {f['network/gapJunctions'].shape[0]}")
                     return None
 
@@ -425,7 +421,7 @@ def get_merge_info(self):
         self.write_log(f"Found merge info in {self.merge_info_file}")
 
         return merge_files_syn, merge_neuron_range_syn, merge_syn_ctr, \
-            merge_files_gj, merge_neuron_range_gj, merge_gj_ctr
+               merge_files_gj, merge_neuron_range_gj, merge_gj_ctr
 
     ############################################################################
 
@@ -666,7 +662,7 @@ def check_network_config_integrity(self, config_file):
         for con in prune_config["Connectivity"]:
             if con not in detect_config["Connectivity"]:
                 self.write_log(f"!!! Connection {con} is present in {config_file}, "
-                               f"but was not included in config file used for detect. " 
+                               f"but was not included in config file used for detect. "
                                f"Please rerun snudda detect", is_error=True)
                 all_present = False
 
@@ -858,12 +854,13 @@ def setup_output_file(self, output_file=None, save_morphologies=False):
                                      maxshape=(None, 11),
                                      compression=self.h5compression)
 
-        num_synapses = np.zeros((1,), dtype=np.uint64)
-        num_gap_junctions = np.zeros((1,), dtype=np.uint64)
+        # num_synapses = np.zeros((1,), dtype=np.uint64)
+        # num_gap_junctions = np.zeros((1,), dtype=np.uint64)
+        # network_group.create_dataset("nSynapses", data=num_synapses, dtype=np.uint64)
+        # network_group.create_dataset("nGapJunctions", data=num_gap_junctions, dtype=np.uint64)
 
-        network_group.create_dataset("nSynapses", data=num_synapses, dtype=np.uint64)
-        network_group.create_dataset("nGapJunctions", data=num_gap_junctions,
-                                     dtype=np.uint64)
+        network_group.create_dataset("nSynapses", data=0, dtype=np.uint64)
+        network_group.create_dataset("nGapJunctions", data=0, dtype=np.uint64)
 
         self.out_file = out_file
 
@@ -1081,8 +1078,8 @@ def prune_synapses_parallel(self, synapse_file,
 
             end_time2 = timeit.default_timer()
             self.write_log(f"prune_synapses_parallel "
-                           f"({syn_after_merge}/{syn_before.sum()} {merge_data_type}, " 
-                           f"{(100*syn_after_merge/np.maximum(1, syn_before.sum())):.1f}% kept)"
+                           f"({syn_after_merge}/{syn_before.sum()} {merge_data_type}, "
+                           f"{(100 * syn_after_merge / np.maximum(1, syn_before.sum())):.1f}% kept)"
                            f": {end_time2 - start_time:.1f}s", force_print=True)
 
         else:
@@ -1102,8 +1099,11 @@ def prune_synapses_parallel(self, synapse_file,
                      f"received {syn_before_total}, expected {synapse_ctr.sum()}")
 
             # Need to resize synapse matrix
-            n_synapses = self.out_file["network/nSynapses"][0]
-            n_gj = self.out_file["network/nGapJunctions"][0]
+            # n_synapses = self.out_file["network/nSynapses"][0]
+            # n_gj = self.out_file["network/nGapJunctions"][0]
+            n_synapses = self.out_file["network/nSynapses"][()]
+            n_gj = self.out_file["network/nGapJunctions"][()]
+
             self.out_file["network/synapses"].resize((n_synapses, self.out_file["network/synapses"].shape[1]))
             self.out_file["network/gapJunctions"].resize((n_gj, self.out_file["network/gapJunctions"].shape[1]))
 
@@ -1173,7 +1173,7 @@ def combine_files(self, source_filenames, merge_data_type, output_filename=None)
                 next_syn += n
             f.close()
 
-        self.out_file["network/" + h5_syn_n][0] = next_syn
+        self.out_file["network/" + h5_syn_n][()] = next_syn
 
         end_time2 = timeit.default_timer()
         self.write_log(f"combine_files ({merge_data_type}): {end_time2 - start_time:.1f}s")
@@ -1331,7 +1331,7 @@ def setup_parallel(self, d_view):
                      "random_seed": self.random_seed,
                      "config_file": self.config_file}, block=True)
 
-        cmd_str = ("sp = SnuddaPrune(network_path=network_path, logfile_name=logfile_name[0]," 
+        cmd_str = ("sp = SnuddaPrune(network_path=network_path, logfile_name=logfile_name[0],"
                    "                 config_file=config_file,"
                    "                 role='worker',random_seed=random_seed)")
         d_view.execute(cmd_str, block=True)
@@ -1506,7 +1506,7 @@ def gather_neuron_synapses(self):
         self.write_log(f"gather_neuron_synapses took {end_time - start_time:.1f} s")
 
         return merge_files_syn, merge_neuron_range_syn, merge_syn_ctr, \
-            merge_files_gj, merge_neuron_range_gj, merge_gj_ctr
+               merge_files_gj, merge_neuron_range_gj, merge_gj_ctr
 
     ############################################################################
 
@@ -1659,7 +1659,7 @@ def big_merge_helper(self, neuron_range, merge_data_type):
             if merge_data_type == "synapses" and self.num_projection_synapses > 0:
 
                 assert os.path.exists(self.projection_synapse_file), \
-                  f"Missing projection connection file: {self.projection_synapse_file}"
+                    f"Missing projection connection file: {self.projection_synapse_file}"
 
                 self.write_log(f"Adding projection synapses from {self.projection_synapse_file}")
                 # There is also a file with synapse connections, add it to the merge set
@@ -1953,7 +1953,7 @@ def prune_synapses_helper(self, synapses, output_file, merge_data_type):
             else:
                 while (read_end_idx < read_end_of_range and
                        (synapses[next_read_pos, 0:2] == synapses[read_end_idx, 0:2]).all()  # Same neuron pair
-                        and synapses[next_read_pos, 6] == synapses[read_end_idx, 6]):       # Same synapse type
+                       and synapses[next_read_pos, 6] == synapses[read_end_idx, 6]):  # Same synapse type
                     read_end_idx += 1
 
                 if self.all_neuron_pair_synapses_share_parameter_id:
@@ -1983,10 +1983,10 @@ def prune_synapses_helper(self, synapses, output_file, merge_data_type):
 
                 assert (synapses[next_read_pos:read_end_idx, 6] == synapse_type).all(), \
                     (f"More than one synapse type connecting "
-                     f"{self.hist_file['network/neurons/name'][synapses[next_read_pos,0]]}  "
-                     f"(ID {synapses[next_read_pos,0]}) and "
-                     f"{self.hist_file['network/neurons/name'][synapses[next_read_pos,1]]} "
-                     f"(ID {synapses[next_read_pos,1]})")
+                     f"{self.hist_file['network/neurons/name'][synapses[next_read_pos, 0]]}  "
+                     f"(ID {synapses[next_read_pos, 0]}) and "
+                     f"{self.hist_file['network/neurons/name'][synapses[next_read_pos, 1]]} "
+                     f"(ID {synapses[next_read_pos, 1]})")
 
             con_id = (self.type_id_list[src_id], self.type_id_list[dest_id], synapse_type)
 
@@ -2031,7 +2031,7 @@ def prune_synapses_helper(self, synapses, output_file, merge_data_type):
             # a3       -1
             # p_mu     -2
 
-            random_pool = post_rng.random(n_pair_synapses*3 + 2)
+            random_pool = post_rng.random(n_pair_synapses * 3 + 2)
 
             # 3. This is the last step of pruning, but we move it to the top
             # since there is no point doing the other steps if we going to
@@ -2054,7 +2054,7 @@ def prune_synapses_helper(self, synapses, output_file, merge_data_type):
                 p = numexpr.evaluate(dist_p)
 
                 frac_flag = random_pool[:n_pair_synapses] < f1
-                dist_flag = random_pool[n_pair_synapses:2*n_pair_synapses] < p
+                dist_flag = random_pool[n_pair_synapses:2 * n_pair_synapses] < p
 
                 keep_row_flag[next_read_pos:read_end_idx] = np.logical_and(frac_flag, dist_flag)
 
@@ -2070,7 +2070,7 @@ def prune_synapses_helper(self, synapses, output_file, merge_data_type):
                 p_keep = np.divide(2 * soft_max, (1 + np.exp(-(n_keep - soft_max) / 5)) * n_keep)
 
                 keep_row_flag[next_read_pos:read_end_idx] = \
-                    np.logical_and(p_keep > random_pool[2*n_pair_synapses:3*n_pair_synapses],
+                    np.logical_and(p_keep > random_pool[2 * n_pair_synapses:3 * n_pair_synapses],
                                    keep_row_flag[next_read_pos:read_end_idx])
 
                 n_keep = np.sum(keep_row_flag[next_read_pos:read_end_idx])
@@ -2081,7 +2081,6 @@ def prune_synapses_helper(self, synapses, output_file, merge_data_type):
                 p_mu = 1.0 / (1.0 + np.exp(-8.0 / mu2 * (n_keep - mu2)))
 
                 if p_mu < random_pool[-2]:
-
                     # Too few synapses, remove all -- need to update keepRowFlag
                     keep_row_flag[next_read_pos:read_end_idx] = 0
                     next_read_pos = read_end_idx
@@ -2112,13 +2111,13 @@ def prune_synapses_helper(self, synapses, output_file, merge_data_type):
                     keep_idx = lookup_idx[keep_idx]
 
                 keep_row_flag[next_read_pos:read_end_idx] = 0
-                keep_row_flag[next_read_pos+keep_idx] = 1
+                keep_row_flag[next_read_pos + keep_idx] = 1
 
             next_read_pos = read_end_idx
 
         # Time to write synapses to file
         n_keep_tot = sum(keep_row_flag)
-        write_start_pos = int(output_file["network/" + h5_syn_n][0])
+        write_start_pos = int(output_file["network/" + h5_syn_n][()])
         write_end_pos = write_start_pos + n_keep_tot
 
         if n_keep_tot > 0:
@@ -2127,7 +2126,7 @@ def prune_synapses_helper(self, synapses, output_file, merge_data_type):
                 synapses[keep_row_flag, :]
 
             # Update counters
-            output_file["network/" + h5_syn_n][0] = write_end_pos
+            output_file["network/" + h5_syn_n][()] = write_end_pos
 
         else:
             self.write_log("No synapses kept, resizing")
@@ -2293,11 +2292,11 @@ def synapse_set_iterator(h5mat_lookup, h5mat, chunk_size=10000, lookup_iterator=
 
                 # Need to concatenate with old synapses
                 syn_mat = np.concatenate([old_synapses,
-                                         read_buffer[:(end_idx - buffer_start), :]],
+                                          read_buffer[:(end_idx - buffer_start), :]],
                                          axis=0)
 
                 assert end_idx == buffer_end \
-                    or (read_buffer[start_idx - buffer_start, :2] != read_buffer[end_idx - buffer_start, :2]).any(), \
+                       or (read_buffer[start_idx - buffer_start, :2] != read_buffer[end_idx - buffer_start, :2]).any(), \
                     "We missed one synapse! (2)"
 
                 assert (syn_mat[:, 0] == syn_mat[0, 0]).all() and (syn_mat[:, 1] == syn_mat[0, 1]).all(), \
@@ -2315,10 +2314,10 @@ def synapse_set_iterator(h5mat_lookup, h5mat, chunk_size=10000, lookup_iterator=
                 assert end_idx == buffer_end \
                        or (read_buffer[start_idx - buffer_start, :2]
                            != read_buffer[end_idx - buffer_start, :2]).any(), \
-                       "We missed one synapse! (1)"
+                    "We missed one synapse! (1)"
 
                 assert (syn_mat[:, 0] == syn_mat[0, 0]).all() and (syn_mat[:, 1] == syn_mat[0, 1]).all(), \
-                       "Synapse matrix (1) contains more than one pair:\n{syn_mat}"
+                    "Synapse matrix (1) contains more than one pair:\n{syn_mat}"
 
                 assert syn_mat.shape[0] == end_idx - start_idx, \
                     "Synapse matrix has wrong size"
@@ -2335,7 +2334,7 @@ def get_neuron_random_seeds(self):
         num_neurons = self.hist_file["network/neurons/neuronID"].shape[0]
 
         if self.cache_neuron_seeds is not None \
-            and self.cache_old_seed == self.random_seed \
+                and self.cache_old_seed == self.random_seed \
                 and self.cache_num_neurons == num_neurons:
 
             neuron_seeds = self.cache_neuron_seeds
@@ -2372,6 +2371,7 @@ def cleanup(self):
                     except:
                         self.write_log(f"cleanup: Failed to close {f}, is it already closed?")
 
+
 ##############################################################################
 
 
diff --git a/snudda/init/init.py b/snudda/init/init.py
index 315b82421..a06b1b343 100644
--- a/snudda/init/init.py
+++ b/snudda/init/init.py
@@ -3,24 +3,25 @@
 # !!! Currently writing full path for the files in the snudda data directory
 #     this makes moving between computers difficult. Fix...
 
+import collections
+import glob
+import json
+import os.path
+import sys
+
+import numexpr
 #
 # Add a function so that $SNUDDADATA refers to the base datapath for snudda
 #
 import numpy as np
-import numexpr
-import sys
-import os.path
-import glob
-import collections
+
 from snudda.place.create_cube_mesh import create_cube_mesh
 from snudda.place.create_slice_mesh import create_slice_mesh
-
-import json
-from snudda.utils.snudda_path import snudda_parse_path, snudda_simplify_path
-from snudda.utils.snudda_path import snudda_path_exists
+from snudda.utils.numpy_encoder import NumpyEncoder
 from snudda.utils.snudda_path import snudda_isdir
 from snudda.utils.snudda_path import snudda_isfile
-from snudda.utils.numpy_encoder import NumpyEncoder
+from snudda.utils.snudda_path import snudda_parse_path, snudda_simplify_path
+from snudda.utils.snudda_path import snudda_path_exists
 
 
 class SnuddaInit(object):
@@ -67,7 +68,7 @@ def __init__(self,
 
         if self.config_file and self.network_path:
             assert self.network_path == os.path.dirname(self.config_file), \
-               f"network_path {self.network_path} and config_file path {self.config_file} must match"
+                f"network_path {self.network_path} and config_file path {self.config_file} must match"
 
         self.network_data["Connectivity"] = dict([])
         self.network_data["Neurons"] = dict([])
@@ -468,11 +469,11 @@ def add_neurons(self, name,
                     hoc_file = [None]
 
                 neuron_file_list.append((d,
-                                        swc_file,
-                                        par_file,
-                                        mech_file,
-                                        modulation_file,
-                                        hoc_file[0]))
+                                         swc_file,
+                                         par_file,
+                                         mech_file,
+                                         modulation_file,
+                                         hoc_file[0]))
 
         # First check how many unique cells we hava available, then we
         # calculate how many of each to use in simulation
@@ -600,7 +601,7 @@ def get_morphologies(neuron_dir):
         else:
             swc_file = glob.glob(os.path.join(snudda_parse_path(neuron_dir), "*swc"))
             assert len(swc_file) == 1, \
-                (f"If no morphology is given in parameter.json then " 
+                (f"If no morphology is given in parameter.json then "
                  f"{snudda_parse_path(neuron_dir)} should contain exactly one swc file")
 
             swc_file = snudda_simplify_path(swc_file[0])
@@ -740,7 +741,6 @@ def add_population_unit_density(self,
             self.network_data["PopulationUnits"][structure_name]["neuronTypes"].append(neuron_types)
             self.network_data["PopulationUnits"][structure_name]["numNeurons"].append(num_neurons)
 
-
     def add_population_unit_random(self, structure_name, neuron_types, fraction_of_neurons, unit_id=None):
 
         if type(neuron_types) != list:
@@ -893,7 +893,7 @@ def define_striatum(self,
             # 1.73 million neurons, volume of allen striatal mesh is 21.5mm3
             striatum_volume = 1e-9 * num_neurons / neuron_density  # 80.5e3
             striatum_side_len = striatum_volume ** (1. / 3)
-            striatum_centre = np.array([4750e-6,4000e-6, 7750e-6])
+            striatum_centre = np.array([4750e-6, 4000e-6, 7750e-6])
 
             if num_neurons < 500:
                 mesh_bin_width = striatum_side_len
@@ -1169,7 +1169,7 @@ def define_striatum(self,
                                target_name="dSPN",
                                connection_type="GABA",
                                dist_pruning=SPN2SPNdistDepPruning,
-                               f1=0.38*0.75, soft_max=3, mu2=2.4,
+                               f1=0.38 * 0.75, soft_max=3, mu2=2.4,
                                a3=P11withinUnit,
                                a3_other=P11betweenUnit,
                                conductance=MSD1gGABA,
@@ -1185,7 +1185,7 @@ def define_striatum(self,
                                target_name="iSPN",
                                connection_type="GABA",
                                dist_pruning=SPN2SPNdistDepPruning,
-                               f1=0.20*0.82, soft_max=3, mu2=2.4,
+                               f1=0.20 * 0.82, soft_max=3, mu2=2.4,
                                a3=P12withinUnit,
                                a3_other=P12betweenUnit,
                                conductance=MSD1gGABA,
@@ -1256,7 +1256,7 @@ def define_striatum(self,
                                target_name="dSPN",
                                connection_type="GABA",
                                dist_pruning=SPN2SPNdistDepPruning,
-                               f1=0.3*0.93, soft_max=4, mu2=2.4,
+                               f1=0.3 * 0.93, soft_max=4, mu2=2.4,
                                a3=P21withinUnit,
                                a3_other=P21betweenUnit,
                                conductance=MSD2gGABA,
@@ -1389,7 +1389,7 @@ def define_striatum(self,
                                target_name="dSPN",
                                connection_type="GABA",
                                dist_pruning=LTSDistDepPruning,
-                               f1=1.0*0.3, soft_max=15, mu2=3, a3=0.3,
+                               f1=1.0 * 0.3, soft_max=15, mu2=3, a3=0.3,
                                conductance=LTSgGABA,
                                cluster_synapses=False,
                                parameter_file=pfLTSdSPN,
@@ -1402,7 +1402,7 @@ def define_striatum(self,
                                target_name="iSPN",
                                connection_type="GABA",
                                dist_pruning=LTSDistDepPruning,
-                               f1=1.0*0.3, soft_max=15, mu2=3, a3=0.3,
+                               f1=1.0 * 0.3, soft_max=15, mu2=3, a3=0.3,
                                conductance=LTSgGABA,
                                cluster_synapses=False,
                                parameter_file=pfLTSiSPN,
@@ -1529,8 +1529,10 @@ def define_cortex(self, num_neurons, d_min=None, neurons_dir=None):
 
         # We should have both ipsi and contra, M1 and S1 input, for now
         # picking one
-        cortexSynParMS = os.path.join("$SNUDDA_DATA", "synapses", "striatum", "M1RH_Analysis_190925.h5-parameters-MS.json")
-        cortexSynParFS = os.path.join("$SNUDDA_DATA", "synapses", "striatum", "M1RH_Analysis_190925.h5-parameters-FS.json")
+        cortexSynParMS = os.path.join("$SNUDDA_DATA", "synapses", "striatum",
+                                      "M1RH_Analysis_190925.h5-parameters-MS.json")
+        cortexSynParFS = os.path.join("$SNUDDA_DATA", "synapses", "striatum",
+                                      "M1RH_Analysis_190925.h5-parameters-FS.json")
 
         self.add_neuron_target(neuron_name="CortexAxon",
                                target_name="dSPN",
@@ -1601,9 +1603,9 @@ def define_thalamus(self, num_neurons, d_min=None, neurons_dir=None):
         # Define targets
 
         thalamus_syn_par_ms = os.path.join("$SNUDDA_DATA", "synapses", "striatum",
-                                        "TH_Analysis_191001.h5-parameters-MS.json")
+                                           "TH_Analysis_191001.h5-parameters-MS.json")
         thalamus_syn_par_fs = os.path.join("$SNUDDA_DATA", "synapses", "striatum",
-                                        "TH_Analysis_191001.h5-parameters-FS.json")
+                                           "TH_Analysis_191001.h5-parameters-FS.json")
 
         thalamus_glut_cond = [1e-9, 0.1e-9]
 
@@ -1692,31 +1694,31 @@ def setup_random_seeds(random_seed=None):
 
     if full_striatum:
         struct_def = {"Striatum": 1730000,
-                     "GPe": 28500,
-                     "GPi": 2000,
-                     "SNr": 20800,
-                     "STN": 8400,
-                     "Cortex": 1,
-                     "Thalamus": 1}
+                      "GPe": 28500,
+                      "GPi": 2000,
+                      "SNr": 20800,
+                      "STN": 8400,
+                      "Cortex": 1,
+                      "Thalamus": 1}
 
         # !!! TEMP, only do stratium for now
         struct_def = {"Striatum": 1730000,
-                     "GPe": 0,
-                     "GPi": 0,
-                     "SNr": 0,
-                     "STN": 0,
-                     "Cortex": 0,
-                     "Thalamus": 0}
+                      "GPe": 0,
+                      "GPi": 0,
+                      "SNr": 0,
+                      "STN": 0,
+                      "Cortex": 0,
+                      "Thalamus": 0}
 
 
     else:
         struct_def = {"Striatum": 100000,
-                     "GPe": 0,
-                     "GPi": 0,
-                     "SNr": 0,
-                     "STN": 0,
-                     "Cortex": 0,
-                     "Thalamus": 0}
+                      "GPe": 0,
+                      "GPi": 0,
+                      "SNr": 0,
+                      "STN": 0,
+                      "Cortex": 0,
+                      "Thalamus": 0}
 
     nTotals = 0
     for x in struct_def:
diff --git a/snudda/input/input.py b/snudda/input/input.py
index 04ffd3199..d8737ac76 100644
--- a/snudda/input/input.py
+++ b/snudda/input/input.py
@@ -15,20 +15,17 @@
 
 # TODO: Randomise conductance for the inputs and store it, use it later when adding external synapses in simulate.py
 
+import json
+import os
 import sys
 from collections import OrderedDict
 
-import numpy as np
-import json
-import os
-from glob import glob
-import itertools
 import h5py
+import numpy as np
 
 from snudda.neurons.neuron_prototype import NeuronPrototype
-from snudda.utils.snudda_path import snudda_parse_path
-from snudda.neurons.neuron_morphology import NeuronMorphology
 from snudda.utils.load import SnuddaLoad
+from snudda.utils.snudda_path import snudda_parse_path
 
 nl = None
 
@@ -137,7 +134,7 @@ def __init__(self,
         self.network_slurm_id = None
         self.population_unit_id = []
 
-        self.use_meta_input=use_meta_input
+        self.use_meta_input = use_meta_input
 
         self.neuron_id = []
         self.neuron_name = []
@@ -250,7 +247,7 @@ def write_hdf5(self):
         self.write_log(f"Writing spikes to {self.spike_data_filename}", force_print=True)
 
         out_file = h5py.File(self.spike_data_filename, 'w', libver=self.h5libver)
-        config_data = out_file.create_dataset("config", data=json.dumps(self.input_info, indent=4))
+        out_file.create_dataset("config", data=json.dumps(self.input_info, indent=4))
         input_group = out_file.create_group("input")
 
         for neuron_id in self.neuron_input:
@@ -258,7 +255,6 @@ def write_hdf5(self):
             nid_group = input_group.create_group(str(neuron_id))
 
             neuron_type = self.neuron_type[neuron_id]
-            # nName = self.neuronName[neuronID]
 
             for input_type in self.neuron_input[neuron_id]:
 
@@ -470,9 +466,9 @@ def make_neuron_input_parallel(self):
 
         dendrite_location_override_list = []
         if self.use_meta_input:
-                print("--------- Meta.json will be used")
+            self.write_log("Input from meta.json will be used")
         else:
-                print("--------- Meta.json will NOT be used")
+            self.write_log("Input from meta.json will NOT be used")
 
         for (neuron_id, neuron_name, neuron_type, population_unit_id) \
                 in zip(self.neuron_id, self.neuron_name, self.neuron_type, self.population_unit_id):
@@ -669,7 +665,8 @@ def make_neuron_input_parallel(self):
                             f"If you specify dendriteLocation you must also specify morphologyKey"
 
                         assert morphology_key == self.network_data["neurons"][neuron_id]["morphologyKey"], \
-                            f"Neuron {neuron_id} has morphology_key {self.network_data['neurons'][neuron_id]['morphologyKey']}" \
+                            f"Neuron {neuron_id} has morphology_key " \
+                            f"{self.network_data['neurons'][neuron_id]['morphologyKey']}" \
                             f"which does not match what is specified in input JSON file: {morphology_key}"
 
                         dend_location = input_info["dendriteLocation"]
@@ -735,8 +732,6 @@ def make_neuron_input_parallel(self):
             amr = self.d_view.gather("inpt", block=True)
             self.write_log("Results received")
 
-            # amr = list(itertools.chain.from_iterable(input_list))
-            # amr = input_list
         else:
             # If no lbView then we run it in serial
             self.write_log("Running input generation in serial")
@@ -763,8 +758,8 @@ def make_neuron_input_parallel(self):
 
         # Gather the spikes that were generated in parallel
         for neuron_id, input_type, spikes, loc, synapse_density, frq, \
-            jdt, p_uid, cond, corr, timeRange, \
-            mod_file, paramFile, paramList, paramID in amr:
+            jdt, p_uid, cond, corr, timeRange, mod_file, param_file, param_list, param_id in amr:
+
             self.write_log(f"Gathering {neuron_id} - {input_type}")
             self.neuron_input[neuron_id][input_type]["spikes"] = spikes
 
@@ -788,9 +783,9 @@ def make_neuron_input_parallel(self):
 
             self.neuron_input[neuron_id][input_type]["generator"] = "poisson"
             self.neuron_input[neuron_id][input_type]["modFile"] = mod_file
-            self.neuron_input[neuron_id][input_type]["parameterFile"] = paramFile
-            self.neuron_input[neuron_id][input_type]["parameterList"] = paramList
-            self.neuron_input[neuron_id][input_type]["parameterID"] = paramID
+            self.neuron_input[neuron_id][input_type]["parameterFile"] = param_file
+            self.neuron_input[neuron_id][input_type]["parameterList"] = param_list
+            self.neuron_input[neuron_id][input_type]["parameterID"] = param_id
 
         return self.neuron_input
 
@@ -915,6 +910,7 @@ def make_correlated_spikes(self,
             num_spike_trains (int): number of spike trains to generate
             p_keep (float): fraction of shared channel spikes to include in spike train, p_keep=1 (100% correlated)
             rng: Numpy random number stream
+            population_unit_spikes
             ret_pop_unit_spikes (bool): if false, returns only spikes,
                                         if true returns (spikes, population unit spikes)
             jitter_dt (float): amount to jitter all spikes
@@ -991,6 +987,7 @@ def jitter_spikes(spike_trains, dt, rng, time_range=None):
         Args:
             spike_trains: spike times
             dt: amount of jitter
+            rng: Numpy random stream
             time_range (tuple): (start, end) see comment above about wrapping around edges.
 
         """
@@ -1026,6 +1023,7 @@ def raster_plot(spike_times,
         Raster plot of spike trains.
 
         Args:
+            spike_times
             mark_spikes: list of spikes to mark
             mark_idx: index of neuron with spikes to mark
             title: title of plot
@@ -1130,7 +1128,7 @@ def get_master_node_rng(self):
 
     ############################################################################
 
-    def verify_correlation(self, spike_trains, expected_corr=None, dt=0):
+    def verify_correlation(self, spike_trains, dt=0):
 
         """
         Verify correlation. This function is slow.
@@ -1191,8 +1189,7 @@ def dendrite_input_locations(self,
                                  synapse_density=None,
                                  num_spike_trains=None,
                                  cluster_size=None,
-                                 cluster_spread=30e-6,
-                                 input_type=None):
+                                 cluster_spread=30e-6):
 
         """
         Return dendrite input location.
@@ -1204,7 +1201,6 @@ def dendrite_input_locations(self,
             num_spike_trains (int): Number of spike trains
             cluster_size (int): Size of each synaptic cluster (None = No clustering)
             cluster_spread (float): Spread of cluster along dendrite (in meters)
-            input_type (str): Type of input, eg. "Cortical" or "Thalamic"
         """
 
         if synapse_density is None:
@@ -1262,10 +1258,10 @@ def dendrite_input_locations(self,
 
         self.write_log(f"morphology = {morphology}")
 
-        input_info = self.neuron_cache[neuron_name].get_input_parameters(parameter_id=parameter_id,
-                                                                         morphology_id=morphology_id,
-                                                                         parameter_key=parameter_key,
-                                                                         morphology_key=morphology_key)
+        # input_info = self.neuron_cache[neuron_name].get_input_parameters(parameter_id=parameter_id,
+        #                                                                  morphology_id=morphology_id,
+        #                                                                  parameter_key=parameter_key,
+        #                                                                  morphology_key=morphology_key)
 
         return morphology.dendrite_input_locations(synapse_density=synapse_density,
                                                    num_locations=num_spike_trains,
@@ -1321,7 +1317,7 @@ def setup_parallel(self):
         self.write_log(f"nl = SnuddaInput(network_path={self.network_path}"
                        f"input_config_file='{self.input_config_file}'"
                        f", spike_data_filename='{self.spike_data_filename}'"
-                       f", hdf5_nework_file={self.hdf5_network_file}",
+                       f", hdf5_nework_file={self.hdf5_network_file}"
                        f", h5libver={self.h5libver}"
                        f", is_master=False "
                        f", random_seed={self.random_seed}"
@@ -1522,8 +1518,7 @@ def make_input_helper_serial(self,
                                                           num_spike_trains=num_spike_trains,
                                                           rng=rng,
                                                           cluster_size=cluster_size,
-                                                          cluster_spread=cluster_spread,
-                                                          input_type=input_type)
+                                                          cluster_spread=cluster_spread)
 
             num_inputs = input_loc[0].shape[0]
             self.write_log(f"Generating {num_inputs} inputs for {self.neuron_name[neuron_id]}")
diff --git a/snudda/input/input_tuning.py b/snudda/input/input_tuning.py
index 20ba534df..a2bd66ed8 100644
--- a/snudda/input/input_tuning.py
+++ b/snudda/input/input_tuning.py
@@ -1,27 +1,23 @@
 import ast
-import os
-import sys
-import glob
 import collections
+import glob
 import json
+import os
+import sys
+import timeit
 
 import h5py
+import matplotlib.pyplot as plt
+import numpy as np
 
+from snudda.core import Snudda
+from snudda.init.init import SnuddaInit
+from snudda.input.input import SnuddaInput
 from snudda.neurons.neuron_prototype import NeuronPrototype
 from snudda.place.create_cube_mesh import create_cube_mesh
-from snudda.neurons.neuron_morphology import NeuronMorphology
+from snudda.simulate.simulate import SnuddaSimulate
 from snudda.utils import SnuddaLoadNetworkSimulation
-from snudda.utils.reposition_neurons import RepositionNeurons
-from snudda.init.init import SnuddaInit
-from snudda.input.input import SnuddaInput
 from snudda.utils.load import SnuddaLoad
-from snudda.simulate.simulate import SnuddaSimulate
-from snudda.core import Snudda
-import numpy as np
-import timeit
-
-import matplotlib.pyplot as plt
-
 from snudda.utils.snudda_path import snudda_isdir, snudda_parse_path, snudda_simplify_path
 
 
@@ -114,7 +110,7 @@ def setup_network(self, neurons_path=None, num_replicas=10, neuron_types=None,
 
     def setup_input(self, input_type=None, num_input_min=100, num_input_max=1000,
                     input_duration=10,
-                    input_frequency_range=None,use_meta_input=True):
+                    input_frequency_range=None, use_meta_input=True):
 
         if not input_frequency_range:
             input_frequency_range = [1.0]
@@ -137,18 +133,18 @@ def setup_input(self, input_type=None, num_input_min=100, num_input_max=1000,
 
         if input_type == 'cortical':
             synapse_density = synapse_density_cortical_input
-            synapse_parameter_file = { "dspn": cortical_SPN_synapse_parameter_file,
-                                       "ispn": cortical_SPN_synapse_parameter_file,
-                                       "fs": cortical_FS_synapse_parameter_file,
-                                       "lts": cortical_LTS_synapse_parameter_file,
-                                       "chin": cortical_ChIN_synapse_parameter_file }
+            synapse_parameter_file = {"dspn": cortical_SPN_synapse_parameter_file,
+                                      "ispn": cortical_SPN_synapse_parameter_file,
+                                      "fs": cortical_FS_synapse_parameter_file,
+                                      "lts": cortical_LTS_synapse_parameter_file,
+                                      "chin": cortical_ChIN_synapse_parameter_file}
             print("Using cortical synapse density for input.")
         elif input_type == 'thalamic':
             synapse_density = synapse_density_thalamic_input
-            synapse_parameter_file = { "dspn": thalamic_SPN_synapse_parameter_file,
-                                       "ispn": thalamic_SPN_synapse_parameter_file,
-                                       "fs": thalamic_FS_synapse_parameter_file,
-                                       "chin": thalamic_ChIN_synapse_parameter_file }
+            synapse_parameter_file = {"dspn": thalamic_SPN_synapse_parameter_file,
+                                      "ispn": thalamic_SPN_synapse_parameter_file,
+                                      "fs": thalamic_FS_synapse_parameter_file,
+                                      "chin": thalamic_ChIN_synapse_parameter_file}
             print("Using thalamic synapse density for input")
         else:
             synapse_density = "1"
@@ -157,7 +153,7 @@ def setup_input(self, input_type=None, num_input_min=100, num_input_max=1000,
 
         self.create_input_config(input_config_file=self.input_config_file,
                                  input_type=input_type,
-                                 input_frequency=list(self.frequency_range),  #[1.0],
+                                 input_frequency=list(self.frequency_range),  # [1.0],
                                  n_input_min=num_input_min,
                                  n_input_max=num_input_max,
                                  synapse_conductance=0.5e-9,
@@ -169,22 +165,22 @@ def setup_input(self, input_type=None, num_input_min=100, num_input_max=1000,
                          hdf5_network_file=os.path.join(self.network_path, 'network-synapses.hdf5'),
                          spike_data_filename=self.input_spikes_file,
                          time=self.max_time,
-                         logfile=os.path.join(self.network_path,"log","input.txt"),use_meta_input=use_meta_input)
+                         logfile=os.path.join(self.network_path, "log", "input.txt"), use_meta_input=use_meta_input)
         si.generate()
 
         # Info we need to run right duration of simulation
         self.write_tuning_info()
 
-    def analyse_results(self,input_type='', show_plots=False):
-        
+    def analyse_results(self, input_type='', show_plots=False):
+
         frequency_data, voltage_data = self.load_data()
         self.plot_frequency_data(frequency_data, show_plots=show_plots, input_type_name=input_type)
         self.plot_frequency_data_alt(frequency_data, show_plots=show_plots, input_type_name=input_type)
         self.plot_volt_data(voltage_data, show_plots=show_plots, input_type_name=input_type)
         self.plot_volt_vs_ninputs(voltage_data, show_plots=show_plots, input_type_name=input_type)
 
-        print(f"To plot traces:\n" 
-              f"python3 plotting/Network_plot_traces.py {self.network_path}output_volt.txt " 
+        print(f"To plot traces:\n"
+              f"python3 plotting/Network_plot_traces.py {self.network_path}output_volt.txt "
               f"{self.network_path}network-synapses.hdf5 ")
 
     def load_data(self, skip_time=0.0):
@@ -230,7 +226,7 @@ def load_data(self, skip_time=0.0):
 
         frequency_data = dict()
         voltage_data = dict()
-        
+
         for neuron_name in neuron_id_lookup.keys():
             frequency_data[neuron_name] = dict()
             voltage_data[neuron_name] = dict()
@@ -247,7 +243,7 @@ def load_data(self, skip_time=0.0):
                                                                             config_data=input_config,
                                                                             neuron_id=neuron_id,
                                                                             skip_time=skip_time)
-                voltage_data[neuron_name][n_inputs] = self.extract_voltage(volt=volt, 
+                voltage_data[neuron_name][n_inputs] = self.extract_voltage(volt=volt,
                                                                            time=time,
                                                                            config_data=input_config,
                                                                            neuron_id=neuron_id,
@@ -273,7 +269,6 @@ def extract_spikes(self, spike_data, config_data, neuron_id, skip_time=0.0):
 
         for start_time, end_time, input_freq in zip(cfg_data["start"], cfg_data["end"], cfg_data["frequency"]):
 
-
             assert start_time + skip_time < end_time, \
                 f"Too large skip time, no data to analyse. start {start_time} + skip {skip_time} < end {end_time}"
 
@@ -316,7 +311,6 @@ def extract_voltage(self, volt, time, config_data, neuron_id, skip_time=0.0):
         max_voltage = []
 
         for start_time, end_time, input_freq in zip(cfg_data["start"], cfg_data["end"], cfg_data["frequency"]):
-
             assert start_time + skip_time < end_time, "Too large skip time, no data to analyse"
 
             idx = np.where((start_time + skip_time <= time) & (time <= end_time))[0]
@@ -325,7 +319,7 @@ def extract_voltage(self, volt, time, config_data, neuron_id, skip_time=0.0):
             input_frequency.append(input_freq)
             mean_voltage.append(np.mean(v))
             max_voltage.append(np.max(v))
-  
+
         input_frequency = np.array(input_frequency)
         mean_voltage = np.array(mean_voltage)
         max_voltage = np.array(max_voltage)
@@ -369,7 +363,7 @@ def plot_volt_data(self, volt_data, show_plots=True, input_type_name=''):
                     input_type_all = input_type
 
                 legend_text.append(f"n={num_input}")
-                ax.plot(input_freq, mean_voltage,linestyle='-',marker='o')
+                ax.plot(input_freq, mean_voltage, linestyle='-', marker='o')
 
             plt.title(f"{neuron_name} receiving {input_type_all} input")
             plt.xlabel("Input frequency (per synapse)")
@@ -381,8 +375,9 @@ def plot_volt_data(self, volt_data, show_plots=True, input_type_name=''):
                 plt.show()
                 plt.pause(0.001)
 
-            #fig_name = os.path.join(self.network_path, "figures", f"input-scaling-freq-{neuron_name}-mean-voltage-{input_type_name}.pdf")
-            fig_name = os.path.join(self.network_path, "figures", f"input-scaling-freq-{neuron_name}-mean-voltage-{input_type_name}.png")
+            # fig_name = os.path.join(self.network_path, "figures", f"input-scaling-freq-{neuron_name}-mean-voltage-{input_type_name}.pdf")
+            fig_name = os.path.join(self.network_path, "figures",
+                                    f"input-scaling-freq-{neuron_name}-mean-voltage-{input_type_name}.png")
             if not os.path.exists(os.path.dirname(fig_name)):
                 os.mkdir(os.path.dirname(fig_name))
 
@@ -390,6 +385,7 @@ def plot_volt_data(self, volt_data, show_plots=True, input_type_name=''):
 
             if not show_plots:
                 plt.close()
+
     def plot_volt_vs_ninputs(self, volt_data, show_plots=True, input_type_name=''):
 
         for neuron_name in volt_data:
@@ -399,8 +395,8 @@ def plot_volt_vs_ninputs(self, volt_data, show_plots=True, input_type_name=''):
 
             cmap = plt.get_cmap('tab20', len(volt_data[neuron_name]))
             ax.set_prop_cycle('color', [cmap(i) for i in range(0, len(volt_data[neuron_name]))])
-            num_inputs=[]
-            mean_voltages=[]
+            num_inputs = []
+            mean_voltages = []
             for num_input in volt_data[neuron_name]:
                 input_freq, mean_voltage, max_voltage, input_type = volt_data[neuron_name][num_input]
                 num_inputs.append(num_input)
@@ -410,25 +406,25 @@ def plot_volt_vs_ninputs(self, volt_data, show_plots=True, input_type_name=''):
                 else:
                     input_type_all = input_type
 
-            #legend_text.append(f"input freq.={input_freq[0]}Hz")#Currently assumes one frequency used. Fix later if necessary
-            #ax.legend(legend_text)
-            ax.plot(num_inputs, mean_voltages,linestyle = 'None',marker='o')
-            #plt.title(f"{neuron_name} receiving {input_type_all} input")
+            # legend_text.append(f"input freq.={input_freq[0]}Hz")#Currently assumes one frequency used. Fix later if necessary
+            # ax.legend(legend_text)
+            ax.plot(num_inputs, mean_voltages, linestyle='None', marker='o')
+            # plt.title(f"{neuron_name} receiving {input_type_all} input")
             plt.xlabel("Number of synapses")
             plt.ylabel("Mean membrane potential (V)")
-            
 
             if show_plots:
                 plt.ion()
                 plt.show()
                 plt.pause(0.001)
 
-            #fig_name = os.path.join(self.network_path, "figures", f"input-scaling-ninputs-{neuron_name}-mean-voltage-{input_type_name}.pdf")
-            fig_name = os.path.join(self.network_path, "figures", f"input-scaling-ninputs-{neuron_name}-mean-voltage-{input_type_name}.png")
+            # fig_name = os.path.join(self.network_path, "figures", f"input-scaling-ninputs-{neuron_name}-mean-voltage-{input_type_name}.pdf")
+            fig_name = os.path.join(self.network_path, "figures",
+                                    f"input-scaling-ninputs-{neuron_name}-mean-voltage-{input_type_name}.png")
             if not os.path.exists(os.path.dirname(fig_name)):
                 os.mkdir(os.path.dirname(fig_name))
 
-            plt.savefig(fig_name,bbox_inches='tight', dpi=300)
+            plt.savefig(fig_name, bbox_inches='tight', dpi=300)
 
             if not show_plots:
                 plt.close()
@@ -467,8 +463,9 @@ def plot_frequency_data(self, frequency_data, show_plots=True, input_type_name='
                 plt.show()
                 plt.pause(0.001)
 
-            #fig_name = os.path.join(self.network_path, "figures", f"input-scaling-freq-{neuron_name}-{input_type_name}.pdf")
-            fig_name = os.path.join(self.network_path, "figures", f"input-scaling-freq-{neuron_name}-{input_type_name}.png")
+            # fig_name = os.path.join(self.network_path, "figures", f"input-scaling-freq-{neuron_name}-{input_type_name}.pdf")
+            fig_name = os.path.join(self.network_path, "figures",
+                                    f"input-scaling-freq-{neuron_name}-{input_type_name}.png")
             if not os.path.exists(os.path.dirname(fig_name)):
                 os.mkdir(os.path.dirname(fig_name))
 
@@ -546,8 +543,9 @@ def plot_frequency_data_alt(self, frequency_data, show_plots=True, input_type_na
                 plt.show()
                 plt.pause(0.001)
 
-            #fig_name = os.path.join(self.network_path, "figures", f"input-scaling-ninputs-{neuron_name}-{input_type_name}.pdf")
-            fig_name = os.path.join(self.network_path, "figures", f"input-scaling-ninputs-{neuron_name}-{input_type_name}.png")
+            # fig_name = os.path.join(self.network_path, "figures", f"input-scaling-ninputs-{neuron_name}-{input_type_name}.pdf")
+            fig_name = os.path.join(self.network_path, "figures",
+                                    f"input-scaling-ninputs-{neuron_name}-{input_type_name}.png")
             if not os.path.exists(os.path.dirname(fig_name)):
                 os.mkdir(os.path.dirname(fig_name))
 
@@ -630,7 +628,7 @@ def gather_all_neurons(self, neuron_types=None, all_combinations=True):
                         param_key = ni["parameterKey"]
                         morph_key = ni["morphologyKey"]
                         short_name = n_name[:min(10, len(n_name))]
-                        neuron_name = f"{neuron_type}_{short_name}_{param_key}_{morph_key}".replace("-","_")
+                        neuron_name = f"{neuron_type}_{short_name}_{param_key}_{morph_key}".replace("-", "_")
                         all_neurons[neuron_name] = ni
                         neuron_ctr += 1
                 else:
@@ -849,7 +847,7 @@ def add_input(self, input_target, input_type, input_frequency, input_duration,
         assert type(input_frequency) == list, f"add_input: input_freq should be a list: {input_frequency}"
         n_steps = len(input_frequency)
         input_start = input_duration * np.arange(0, n_steps)
-        input_end = input_duration * np.arange(1, n_steps+1)
+        input_end = input_duration * np.arange(1, n_steps + 1)
 
         self.input_info[input_target] = collections.OrderedDict()
         self.input_info[input_target][input_type] = collections.OrderedDict()
@@ -895,7 +893,8 @@ def plot_generated_input(self, num_bins=50):
                     if input_type not in distance_to_soma:
                         distance_to_soma[input_type] = []
 
-                    distance_to_soma[input_type].append(input_spike_data["input"][str(nid)][input_type]["distanceToSoma"][:])
+                    distance_to_soma[input_type].append(
+                        input_spike_data["input"][str(nid)][input_type]["distanceToSoma"][:])
 
             plt.title(f"Input to {nt}")
             plt.xlabel("Time (s)")
@@ -915,7 +914,7 @@ def plot_generated_input(self, num_bins=50):
             leg = []
             for input_type in distance_to_soma:
                 leg.append(input_type)
-                ax2.hist(np.concatenate(distance_to_soma[input_type])*1e6, 50, histtype="step")
+                ax2.hist(np.concatenate(distance_to_soma[input_type]) * 1e6, 50, histtype="step")
 
             plt.legend(leg)
             plt.title(f"Synapses onto {nt}")
@@ -938,7 +937,6 @@ def simulate(self, mech_dir=None):
         # Get info so we can set max_time correctly
         self.read_tuning_info()
 
-        from mpi4py import MPI
         from neuron import h  # , gui
         start = timeit.default_timer()
 
@@ -950,7 +948,7 @@ def simulate(self, mech_dir=None):
         sim.add_external_input()
         sim.check_memory_status()
 
-        #sim.add_volt_recording()
+        # sim.add_volt_recording()
         sim.add_volt_recording_soma()
 
         t_sim = self.max_time * 1000  # Convert from s to ms for Neuron simulator
@@ -1005,16 +1003,17 @@ def write_tuning_info(self):
         pythonidx = sys.argv.index('-python')
         if len(sys.argv) > pythonidx:
             sys.argv = sys.argv[pythonidx + 1:]
-    
+
     from argparse import ArgumentParser, RawTextHelpFormatter
 
     parser = ArgumentParser("Input Scaling", formatter_class=RawTextHelpFormatter)
     parser.add_argument("action", choices=["setup", "simulate", "analyse"], help="Action to run.")
     parser.add_argument("networkPath", help="Network path")
     parser.add_argument("--neurons", help="Neurons path")
-    parser.add_argument("--mechDir", type=str, help="Path to mechanisms",default=None)
+    parser.add_argument("--mechDir", type=str, help="Path to mechanisms", default=None)
     parser.add_argument("--input_type", help="Type of external input",
-                        choices=["thalamic", "cortical","corticothalamic"], default="thalamic")#only use corticalthalamic in analyse
+                        choices=["thalamic", "cortical", "corticothalamic"],
+                        default="thalamic")  # only use corticalthalamic in analyse
     parser.add_argument("--numInputSteps", type=int, help="Number of steps for number of inputs to neurons",
                         default=10)
     parser.add_argument("--numInputMin", type=int, help="Minimum number of synaptic inputs of input_type", default=100)
@@ -1067,7 +1066,6 @@ def write_tuning_info(self):
     else:
         print(f"Unknown action {args.action}")
 
-
     # python3 input_tuning/input_tuning.py setup networks/input_scaling_v1/ data/neurons/striatum/
     # mpiexec -n 4 python3 input_tuning/input_tuning.py simulate networks/input_scaling_v1/ < input.txt &> output-tuning.txt &
 
diff --git a/snudda/input/inspectinput.py b/snudda/input/inspectinput.py
index 8bb154d23..578169e45 100644
--- a/snudda/input/inspectinput.py
+++ b/snudda/input/inspectinput.py
@@ -1,96 +1,94 @@
 import os
+
 import h5py
+
 from snudda.utils.load import SnuddaLoad
 
+
 class InspectInput(object):
 
-  def __init__(self,networkFile,inputFile):
+    def __init__(self, network_file, input_file):
 
-    self.networkFile = networkFile
-    self.inputFile = inputFile
+        self.network_file = network_file
+        self.input_file = input_file
 
-    # We just need this to identify which neuron is which
-    self.network = SnuddaLoad(self.networkFile, load_synapses=False)
+        # We just need this to identify which neuron is which
+        self.network = SnuddaLoad(self.network_file, load_synapses=False)
 
-    self.inputData = h5py.File(inputFile,'r')
+        self.input_data = h5py.File(input_file, 'r')
 
+    def get_morphologies(self):
 
-  def getMorphologies(self):
+        return [os.path.basename(c["morphology"]) \
+                for c in self.network.data["neurons"]]
 
-    return [os.path.basename(c["morphology"]) \
-            for c in self.network.data["neurons"]]
+    def get_input_types(self, cell_id):
 
+        s_cell_id = [str(c) for c in cell_id]
+        input_types = set()
 
-  def getInputTypes(self,cellID):
+        for sc_id in s_cell_id:
+            inp_t = set([inp for inp in self.input_data["input"][sc_id]])
+            input_types = input_types.union(inp_t)
 
-    sCellID = [str(c) for c in cellID]
-    inputTypes = set()
-    
-    for scID in sCellID:
-      inpT = set([inp for inp in self.inputData["input"][scID]])
-      inputTypes = inputTypes.union(inpT)
-      
-    return list(inputTypes)
+        return list(input_types)
 
-  
-  def checkInputRatio(self, neuronType, verbose=True):
+    def check_input_ratio(self, neuron_type, verbose=True):
 
-    print(f"Counting inputs for {neuronType}")
-    
-    cellID = self.network.get_neuron_id_of_type(neuronType)
-    cellIDstr = [str(c) for c in cellID]
-    
-    inputCount = dict()
+        print(f"Counting inputs for {neuron_type}")
 
-    cellMorph = self.getMorphologies()
+        cell_id = self.network.get_neuron_id_of_type(neuron_type)
+        cell_id_str = [str(c) for c in cell_id]
 
-    uniqueMorph = set([cellMorph[c] for c in cellID])
+        input_count = dict()
 
-    inputTypeList = self.getInputTypes(cellID)
-    
-    for inp in inputTypeList:
-      inputCount[inp] = dict()
-      for um in uniqueMorph:
-        inputCount[inp][um] = 0
+        cell_morph = self.get_morphologies()
 
-    morphCounter = dict()
+        unique_morph = set([cell_morph[c] for c in cell_id])
 
-    for um in uniqueMorph:
-      morphCounter[um] = 0
-        
-      
-    # !!! TODO: We should split this by morphology also...
-      
-    for cID in self.inputData['input']:
-      if cID in cellIDstr:
-        morph = cellMorph[int(cID)]
-        morphCounter[morph] += 1
-                          
-        for inp in inputTypeList:
-          if inp in self.inputData['input'][cID]:
-            nInput = len(self.inputData['input'][cID][inp]['nSpikes'])
-            inputCount[inp][morph] += nInput
+        input_type_list = self.get_input_types(cell_id)
 
-    for inp in inputTypeList:
-      for um in uniqueMorph:
-        avgInp = round(inputCount[inp][um]/morphCounter[um],1)
-        print(f"{inp} morphology {um}: {avgInp} inputs")
-        
-    return inputCount
+        for inp in input_type_list:
+            input_count[inp] = dict()
+            for um in unique_morph:
+                input_count[inp][um] = 0
 
+        morph_counter = dict()
 
-if __name__ == '__main__':
+        for um in unique_morph:
+            morph_counter[um] = 0
+
+        # !!! TODO: We should split this by morphology also...
+
+        for c_id in self.input_data['input']:
+            if c_id in cell_id_str:
+                morph = cell_morph[int(c_id)]
+                morph_counter[morph] += 1
 
-  from argparse import ArgumentParser
+                for inp in input_type_list:
+                    if inp in self.input_data['input'][c_id]:
+                        n_input = len(self.input_data['input'][c_id][inp]['nSpikes'])
+                        input_count[inp][morph] += n_input
+
+        for inp in input_type_list:
+            for um in unique_morph:
+                avg_inp = round(input_count[inp][um] / morph_counter[um], 1)
+                print(f"{inp} morphology {um}: {avg_inp} inputs")
+
+        return input_count
+
+
+if __name__ == '__main__':
+    from argparse import ArgumentParser
 
-  parser = ArgumentParser(description="Inspect input")
-  parser.add_argument("networkFile", help="Network file (hdf5)",type=str)
-  parser.add_argument("inputFile", help="Input file (hdf5)",type=str)
-  parser.add_argument("neuronType", help="Neuron type",type=str)
+    parser = ArgumentParser(description="Inspect input")
+    parser.add_argument("networkFile", help="Network file (hdf5)", type=str)
+    parser.add_argument("inputFile", help="Input file (hdf5)", type=str)
+    parser.add_argument("neuronType", help="Neuron type", type=str)
 
-  args = parser.parse_args()
+    args = parser.parse_args()
 
-  inspector = InspectInput(networkFile=args.networkFile,
-                           inputFile=args.inputFile)
+    inspector = InspectInput(network_file=args.networkFile,
+                             input_file=args.inputFile)
 
-  inspector.checkInputRatio(neuronType=args.neuronType)
+    inspector.check_input_ratio(neuron_type=args.neuronType)
diff --git a/snudda/neurons/index_tree.py b/snudda/neurons/index_tree.py
new file mode 100644
index 000000000..394462d31
--- /dev/null
+++ b/snudda/neurons/index_tree.py
@@ -0,0 +1,81 @@
+import igraph
+
+
+class IndexTree(igraph.Graph):
+
+    def __init__(self, links, coords):
+
+        super().__init__(directed=True)
+
+        self.add_vertices(coords.shape[0])
+        self.add_edges(links)
+
+        self.coords = coords
+
+    # Kom på ett bra namn.
+    def walk(self, distance, direction):
+
+        """ Returns all compartments within distance in direction = None, Proximal, Distal """
+
+        pass
+
+    def get_path(self):
+
+        pass
+
+    def verify(self):
+        # Check SWC file is not circular
+        pass
+
+    def find_parent(self):
+
+        pass
+
+    def find_children(self):
+
+        pass
+
+
+
+    # TODO: Funktionalitet vi vill ha
+    #
+    # -
+
+
+class IndexLookupError(Exception):
+    """Must set a unique value in a BijectiveMap."""
+
+    def __init__(self, value):
+        self.value = value
+        msg = 'The value "{}" is already in the mapping.'
+        super().__init__(msg.format(value))
+
+
+#  Credit to : https://stackoverflow.com/a/34460187
+
+class IndexLookup(dict):
+    """Invertible map."""
+
+    def __init__(self, inverse=None):
+        if inverse is None:
+            inverse = self.__class__(inverse=self)
+        self.inverse = inverse
+
+    def __setitem__(self, key, value):
+        if value in self.inverse:
+            raise IndexLookupError(value)
+
+        self.inverse._set_item(value, key)
+        self._set_item(key, value)
+
+    def __delitem__(self, key):
+        self.inverse._del_item(self[key])
+        self._del_item(key)
+
+    def _del_item(self, key):
+        super().__delitem__(key)
+
+    def _set_item(self, key, value):
+        super().__setitem__(key, value)
+
+
diff --git a/snudda/neurons/neuron_model.py b/snudda/neurons/neuron_model.py
index 3093ce003..c59e301f9 100644
--- a/snudda/neurons/neuron_model.py
+++ b/snudda/neurons/neuron_model.py
@@ -1,13 +1,12 @@
 """ Based on BluePyOpt exampel code by Werner van Geit, 
 modified by Johannes Hjorth """
 
-import os
 import json
+import os
 from collections import OrderedDict
 
-import numpy as np
-
 import bluepyopt.ephys as ephys
+import numpy as np
 
 script_dir = os.path.dirname(__file__)
 config_dir = os.path.join(script_dir, 'config')
@@ -20,7 +19,6 @@ def define_mechanisms(mechanism_config=None):
     """Define mechanisms"""
 
     assert (mechanism_config is not None)
-    # print("Using mechanmism config: " + mechanism_config)
 
     with open(os.path.join(config_dir, mechanism_config), "r") as f:
         mech_definitions = json.load(f, object_pairs_hook=OrderedDict)
@@ -78,9 +76,7 @@ def define_parameters(parameter_config=None):
             bounds = param_config['bounds']
             value = None
         else:
-            raise Exception(
-                'Parameter config has to have bounds or value: %s'
-                % param_config)
+            raise Exception(f"Parameter config has to have bounds or value: {param_config}")
 
         if param_config['type'] == 'global':
             parameters.append(
@@ -124,12 +120,7 @@ def define_parameters(parameter_config=None):
                         bounds=bounds,
                         locations=[seclist_loc]))
         else:
-            raise Exception(
-                'Param config type has to be global, section or range: %s' %
-                param_config)
-
-    # import pdb
-    # pdb.set_trace()
+            raise Exception(f"Param config type has to be global, section or range: {param_config}")
 
     return parameters
 
@@ -141,8 +132,6 @@ def define_morphology(replace_axon=True, morph_file=None):
 
     assert (morph_file is not None)
 
-    # print("Using morphology: " + morph_file)
-
     return ephys.morphologies.NrnFileMorphology(
         os.path.join(
             script_dir,
@@ -238,5 +227,3 @@ def find_dend_compartment(neuron, synapse_xyz, loc_type, sim):
 
     return dend_loc
 
-# Add a generic synapse to location
-# def addSynapse(neuron, location):
diff --git a/snudda/neurons/neuron_model_extended.py b/snudda/neurons/neuron_model_extended.py
index 614918b8b..bba6ccaa8 100644
--- a/snudda/neurons/neuron_model_extended.py
+++ b/snudda/neurons/neuron_model_extended.py
@@ -1,19 +1,16 @@
 """ Based on BluePyOpt exampel code by Werner van Geit, 
 modified by Johannes Hjorth """
 
-import os
 import json
+import os
 from collections import OrderedDict
 
-import numpy as np
-
 import bluepyopt.ephys as ephys
 
 from snudda.neurons.neuron_prototype import NeuronPrototype
 
 
 class NeuronModel(ephys.models.CellModel):
-
     """ Extended NeuronModel for simulation. """
 
     def __init__(self,
@@ -86,9 +83,8 @@ def __init__(self,
         morph = self.define_morphology(replace_axon=True, morph_file=morph_file)
         mechs = self.define_mechanisms(mechanism_config=mech_file)
         params = self.define_parameters(param_file, parameter_id, parameter_key)
-        
+
         if modulation_key and modulation_file:
-            
             mod_params = self.define_parameters(parameter_config=modulation_file, parameter_key=modulation_key)
             params = params + mod_params
 
@@ -112,7 +108,7 @@ def define_mechanisms(self, mechanism_config=None):
 
         if "modpath" in mech_definitions:
             mod_path = os.path.join(self.script_dir, mech_definitions["modpath"])
-            print("mod_path set to " + mod_path + " (not yet implemented)")
+            print(f"mod_path set to {mod_path} (not yet implemented)")
         else:
             mod_path = None
 
@@ -199,9 +195,7 @@ def define_parameters(self, parameter_config=None, parameter_id=None, parameter_
                 bounds = param_config['bounds']
                 value = None
             else:
-                raise Exception(
-                    'Parameter config has to have bounds or value: %s'
-                    % param_config)
+                raise Exception(f"Parameter config has to have bounds or value: {param_config}")
 
             if param_config['type'] == 'global':
                 parameters.append(
@@ -245,12 +239,7 @@ def define_parameters(self, parameter_config=None, parameter_id=None, parameter_
                             bounds=bounds,
                             locations=[seclist_loc]))
             else:
-                raise Exception(
-                    'Param config type has to be global, section or range: %s' %
-                    param_config)
-
-            # import pdb
-            # pdb.set_trace()
+                raise Exception(f"Param config type has to be global, section or range: {param_config}")
 
         return parameters
 
diff --git a/snudda/neurons/neuron_morphology.py b/snudda/neurons/neuron_morphology.py
index 54a545f78..1c33c03e6 100644
--- a/snudda/neurons/neuron_morphology.py
+++ b/snudda/neurons/neuron_morphology.py
@@ -7,16 +7,18 @@
 # etc...
 #
 
-import numpy as np
 import numexpr
+import numpy as np
+
 from snudda.utils.snudda_path import snudda_parse_path
 
+
 # Use np.random.choice for selecting
 
 
 class NeuronMorphology:
-
     """ Neuron morphology object. Also see NeuronPrototype class which handles multiple morphology variations. """
+
     # axonStumpIDFlag should be True if running Network_simulate.py
     # it should be False if we are running Neurodamus simulation.
 
@@ -369,7 +371,8 @@ def place(self, rotation=None, position=None):
         if rotation is not None:
 
             assert np.abs(np.linalg.det(rotation) - 1) < 1e-6, \
-                "place: determinant of rotation matrix should be 1 (did you miss matmul when multiplying?)"
+                (f"place: determinant of rotation matrix should be 1 (did you miss matmul when multiplying?)"
+                 f"rotation = {rotation}, det(rotation) = {np.linalg.det(rotation)}")
 
             self.rotated_flag = True
 
@@ -810,7 +813,7 @@ def load_swc(self, swc_file=None):
             self.dend_sec_x = np.zeros((0, 2))
 
         # Lookup for section length based on section id
-        self.sec_id_to_len = np.ones((int(1+np.max(points[:, 10])),))
+        self.sec_id_to_len = np.ones((int(1 + np.max(points[:, 10])),))
         for sec_id, sec_len in zip(points[:, 10].astype(int), points[:, 11]):
             if sec_id >= 0:
                 self.sec_id_to_len[sec_id] = sec_len
@@ -859,7 +862,7 @@ def get_section_coordinates(self, section_id, section_x):
         p1 = self.dend[self.dend_links[link_idx[0], 0], :3]
         p2 = self.dend[self.dend_links[link_idx[0], 1], :3]
 
-        coords = p2 * section_x + (1-section_x) * p1
+        coords = p2 * section_x + (1 - section_x) * p1
 
         return coords
 
@@ -928,7 +931,6 @@ def plot_neuron(self,
             soma_colour = self.colour
 
         import matplotlib.pyplot as plt
-        from mpl_toolkits.mplot3d import Axes3D
 
         if axis is None:
             fig = plt.figure()
@@ -1003,9 +1005,9 @@ def plot_neuron(self,
 
             if self.soma.shape[0] == 1:
                 u, v = np.mgrid[0:2 * np.pi:20j, 0:np.pi:10j]
-                x = (self.soma[0, 3] * np.cos(u) * np.sin(v) + self.soma[0, 0] - plot_origo[0])*plot_scale
-                y = (self.soma[0, 3] * np.sin(u) * np.sin(v) + self.soma[0, 1] - plot_origo[1])*plot_scale
-                z = (self.soma[0, 3] * np.cos(v) + self.soma[0, 2] - plot_origo[2])*plot_scale
+                x = (self.soma[0, 3] * np.cos(u) * np.sin(v) + self.soma[0, 0] - plot_origo[0]) * plot_scale
+                y = (self.soma[0, 3] * np.sin(u) * np.sin(v) + self.soma[0, 1] - plot_origo[1]) * plot_scale
+                z = (self.soma[0, 3] * np.cos(v) + self.soma[0, 2] - plot_origo[2]) * plot_scale
 
                 ax.plot_wireframe(x, y, z, color=soma_colour, alpha=alpha)
             else:
@@ -1129,7 +1131,7 @@ def dendrite_input_locations(self, synapse_density, rng, num_locations=None,
         dist_syn_soma = []
 
         # x,y,z, secID, secX
-        input_loc = np.zeros((n_syn_tot*cluster_size, 5))
+        input_loc = np.zeros((n_syn_tot * cluster_size, 5))
         d = self.dend[:, 4]
 
         # Iterate over each compartment
@@ -1137,7 +1139,7 @@ def dendrite_input_locations(self, synapse_density, rng, num_locations=None,
         for i_comp, n_syn in enumerate(number_of_synapses):
 
             # Add synapses to that compartment
-            for j in range(0, n_syn*cluster_size):
+            for j in range(0, n_syn * cluster_size):
                 # print('Compartment containing a synapse',iComp)
                 # print('Distance from soma',self.dend[iComp][4]*1e6,'$mum$')
                 input_loc[syn_ctr, 3] = self.dend_sec_id[i_comp]
@@ -1272,7 +1274,7 @@ def dendrite_input_locations_helper(self,
         if cluster_size is None:
             cluster_size = 1
 
-        num_synapses = num_locations*cluster_size
+        num_synapses = num_locations * cluster_size
         input_loc = np.zeros((num_synapses, 6))
 
         d = self.dend[:, 4]
@@ -1283,7 +1285,7 @@ def dendrite_input_locations_helper(self,
         assert exp_sum > 0, f"Check your synapse density {synapse_density}, all elements zero."
 
         syn_idx = rng.choice(len(expected_synapses), size=num_locations, replace=True,
-                             p=expected_synapses/exp_sum)
+                             p=expected_synapses / exp_sum)
 
         for comp_idx in syn_idx:
 
@@ -1311,10 +1313,11 @@ def dendrite_input_locations_helper(self,
             else:
                 syn_info = self.cluster_synapses(sec_id=sec_id, sec_x=sec_x, count=cluster_size,
                                                  distance=cluster_spread, rng=rng)
-                input_loc[syn_ctr:syn_ctr+cluster_size, :3] = syn_info[1]  # Synapse x,y,z -- in global coordinate system(!)
-                input_loc[syn_ctr:syn_ctr + cluster_size, 3] = sec_id      # Sec id
-                input_loc[syn_ctr:syn_ctr + cluster_size, 4] = syn_info[0] # Sec x
-                input_loc[syn_ctr:syn_ctr + cluster_size, 5] = syn_info[2] # Soma distance
+                input_loc[syn_ctr:syn_ctr + cluster_size, :3] = syn_info[
+                    1]  # Synapse x,y,z -- in global coordinate system(!)
+                input_loc[syn_ctr:syn_ctr + cluster_size, 3] = sec_id  # Sec id
+                input_loc[syn_ctr:syn_ctr + cluster_size, 4] = syn_info[0]  # Sec x
+                input_loc[syn_ctr:syn_ctr + cluster_size, 5] = syn_info[2]  # Soma distance
 
                 syn_ctr += cluster_size
 
@@ -1386,7 +1389,8 @@ def debug_plot(self, wait_flag=False, plot_step=1, plot_axon_flag=False):
     parser = ArgumentParser()
     parser.add_argument("file_name", help="Path to neuron file")
     parser.add_argument("--step", default=None,
-                        help="Display segment ID and segment X for sections with segment step for text output (e.g. 10)", type=int)
+                        help="Display segment ID and segment X for sections with segment step for text output (e.g. 10)",
+                        type=int)
     args = parser.parse_args()
 
     nm = NeuronMorphology(swc_filename=args.file_name, verbose=True, use_cache=False)
@@ -1396,23 +1400,7 @@ def debug_plot(self, wait_flag=False, plot_step=1, plot_axon_flag=False):
         nm.debug_plot(plot_step=args.step)
     else:
         import matplotlib.pyplot as plt
+
         nm.plot_neuron(show_plot=False)
         plt.show()
 
-
-    # nm.setAxonDensity("3e9*np.exp(-d/100e-6)",300e-6)
-
-    # nm.plotDensity()
-
-    # ax1 = nm.plot_neuron()
-
-    # print("In main function")
-    # import pdb
-    # pdb.set_trace()
-
-    # nm2 = nm.clone(rotation=nm.rand_rotation_matrix(), position=np.array([0.001, 0.001, 0.001]))
-    # nm2.plot_neuron(ax1)
-
-    # raw_input("Test")
-    # import pdb
-    # pdb.set_trace()
diff --git a/snudda/neurons/neuron_prototype.py b/snudda/neurons/neuron_prototype.py
index 3759fa3e9..929f9cea3 100644
--- a/snudda/neurons/neuron_prototype.py
+++ b/snudda/neurons/neuron_prototype.py
@@ -8,7 +8,6 @@
 
 
 class NeuronPrototype:
-
     """ Helper class, returns a neuron prototype based on parameter_id, morph_id and modulation_id """
 
     def __init__(self,
@@ -162,7 +161,7 @@ def get_morph_key(self, parameter_id, morphology_id, parameter_key=None):
         else:
             par_key = self.get_parameter_key(parameter_id=parameter_id)
             assert parameter_key is None or par_key == parameter_key, \
-                (f"parameter_id = {parameter_id} gives parameter_key {par_key}, " 
+                (f"parameter_id = {parameter_id} gives parameter_key {par_key}, "
                  f"different from parameter_key {parameter_key} provided")
 
         if self.meta_info:
@@ -266,7 +265,7 @@ def get_morphology(self, parameter_id=None, morphology_id=None, parameter_key=No
 
         if morph_path is None:
             print(f"morph_path is None for {self.neuron_name} path: {self.neuron_path}. "
-                  f"Is SNUDDA_DATA set correctly? ({os.environ['SNUDDA_DATA']})")
+                  f"Is SNUDDA_DATA set correctly? ({os.environ['SNUDDA_DATA'] if 'SNUDDA_DATA' in os.environ else None})")
             import pdb
             pdb.set_trace()
 
@@ -407,7 +406,7 @@ def clone(self, parameter_id=None, morphology_id=None, modulation_id=None,
 
         if get_cache_original:
             assert position is None and rotation is None and modulation_id is None, \
-                    "If get_cache_original is passed position, rotation and modulation_id must be None"
+                "If get_cache_original is passed position, rotation and modulation_id must be None"
             morph = self.morphology_cache[morph_tag]
         else:
             # Add the keys also for parameter, morphology and modulation
@@ -431,4 +430,3 @@ def clone(self, parameter_id=None, morphology_id=None, modulation_id=None,
                                                            morphology_key=morphology_key,
                                                            modulation_key=modulation_key)
         return morph
-
diff --git a/snudda/place/create_cube_mesh.py b/snudda/place/create_cube_mesh.py
index aaaec8011..b5bda9f7d 100644
--- a/snudda/place/create_cube_mesh.py
+++ b/snudda/place/create_cube_mesh.py
@@ -1,9 +1,9 @@
-import numpy as np
 import os
 
+import numpy as np
+
 
 def create_cube_mesh(file_name, centre_point, side_len, description=None, verbose=False):
-
     """
     Creates a cube mesh in wavefront file format.
 
diff --git a/snudda/place/create_slice_mesh.py b/snudda/place/create_slice_mesh.py
index 8b43695fb..a531b1cb7 100644
--- a/snudda/place/create_slice_mesh.py
+++ b/snudda/place/create_slice_mesh.py
@@ -1,4 +1,5 @@
 import os
+
 import numpy as np
 
 
@@ -8,7 +9,6 @@ def create_slice_mesh(file_name,
                       y_len=500e-6,
                       z_len=150e-6,
                       description=None):
-
     """
     Create a slice mesh in wavefront format.
 
diff --git a/snudda/place/place.py b/snudda/place/place.py
index abb610485..175655205 100644
--- a/snudda/place/place.py
+++ b/snudda/place/place.py
@@ -9,28 +9,27 @@
 # Grant Agreements No. 720270 and No. 785907, No 945539
 # (Human Brain Project SGA1, SGA2, SGA3).
 
+import json
+import os
 #
 import sys
+from collections import OrderedDict
 
+import h5py
 import numexpr
 import numpy as np
 import scipy.cluster
-import os
-from collections import OrderedDict
-import h5py
-import json
 
 from snudda.neurons.neuron_prototype import NeuronPrototype
-from snudda.utils.snudda_path import snudda_parse_path, snudda_path_exists
 from snudda.place.region_mesh import RegionMesh
 from snudda.place.rotation import SnuddaRotate
+from snudda.utils.snudda_path import snudda_parse_path, snudda_path_exists
 
 ''' This code places all neurons in space, but does not setup their
     connectivity. That is done by detect.py and prune.py '''
 
 
 class SnuddaPlace(object):
-
     """ Places neurons in 3D space. Use detect to add connections, and prune to remove redundant connections. """
 
     def __init__(self,
@@ -391,7 +390,8 @@ def parse_config(self, config_file=None, resort_neurons=True):
                                     (f"Missing Coordinates and/or Density data for "
                                      f"volume {volume_id}, neuron type {neuron_type}")
 
-                                coord = np.array(density_data[volume_id][neuron_type]["Coordinates"]) * 1e-6  # Convert to SI
+                                # Convert to SI (* 1e-6)
+                                coord = np.array(density_data[volume_id][neuron_type]["Coordinates"]) * 1e-6
                                 density = np.array(density_data[volume_id][neuron_type]["Density"])
 
                                 if self.griddata_interpolation:
@@ -906,7 +906,7 @@ def population_unit_density_labeling(self, population_unit_info, neuron_id):
                     in enumerate(zip(centres, neuron_types, probability_functions)):
 
                 if neuron_type in neuron_type_list:
-                    d = np.linalg.norm(pos-centre_pos)
+                    d = np.linalg.norm(pos - centre_pos)
                     unit_probability[idx] = numexpr.evaluate(p_func)
                 else:
                     unit_probability[idx] = 0  # That unit does not contain this neuron type
@@ -952,7 +952,6 @@ def population_unit_density_labeling(self, population_unit_info, neuron_id):
                     else:
                         self.population_units[0] = remove_nid
 
-
     ############################################################################
 
     def init_population_units(self):
@@ -978,7 +977,7 @@ def plot_ranges(self):
         colours = np.zeros((len(self.neurons),))
         r_start = 0
         for idx, r_end in enumerate(range_borders[1:]):
-            colours[r_start:r_end] = idx+1
+            colours[r_start:r_end] = idx + 1
             r_start = r_end
 
         xyz = self.all_neuron_positions()
@@ -999,7 +998,7 @@ def cluster_neurons(self, n_trials=5):
         """
 
         n_workers = len(self.d_view) if self.d_view is not None else 1
-        n_clusters = np.maximum(n_workers*5, 100)
+        n_clusters = np.maximum(n_workers * 5, 100)
         n_clusters = np.minimum(n_clusters, len(self.neurons))
 
         xyz = self.all_neuron_positions()
@@ -1035,7 +1034,7 @@ def cluster_neurons(self, n_trials=5):
                 current_cluster = local_centroid_order[0]
 
                 take_n = np.minimum(len(cluster_member_list[current_cluster]), range_end - range_start)
-                neuron_order[neuron_order_ctr:neuron_order_ctr+take_n] = cluster_member_list[current_cluster][:take_n]
+                neuron_order[neuron_order_ctr:neuron_order_ctr + take_n] = cluster_member_list[current_cluster][:take_n]
                 neuron_order_ctr += take_n
 
                 del cluster_member_list[current_cluster][:take_n]
@@ -1053,7 +1052,7 @@ def cluster_neurons(self, n_trials=5):
                            f"neurons unaccounted for",
                            is_error=True)
             self.write_log(f"incorrect neuron_order={neuron_order} (printed for debugging)")
-            neuron_order = self.cluster_neurons(n_trials=n_trials-1)
+            neuron_order = self.cluster_neurons(n_trials=n_trials - 1)
 
         # TODO: This occured once on Tegner, why did it happen?
         assert np.count_nonzero(neuron_order < 0) == 0, \
@@ -1102,5 +1101,4 @@ def volume_neurons(self, volume_id):
 
 
 if __name__ == "__main__":
-
     assert False, "Please use snudda.py place networks/yournetwork"
diff --git a/snudda/place/projection_map_finder.py b/snudda/place/projection_map_finder.py
index f399eaff2..2682b4208 100755
--- a/snudda/place/projection_map_finder.py
+++ b/snudda/place/projection_map_finder.py
@@ -12,7 +12,6 @@ def __init__(self):
         self.num = 0
 
     def generate_cube(self, centre, side, num):
-
         self.coords = side * np.random.uniform(size=(num, 3))
         self.coords[:, 0] += centre[0]
         self.coords[:, 1] += centre[1]
@@ -22,7 +21,6 @@ def generate_cube(self, centre, side, num):
         self.calc_distance()
 
     def generate_disk(self, centre, side, num):
-
         self.coords = side * np.random.uniform(size=(num, 3))
         self.coords[:, 0] += centre[0]
         self.coords[:, 1] += centre[1]
@@ -38,7 +36,7 @@ def get_colour(self, idx):
         min_coord = np.min(self.coords)
         max_coord = np.max(self.coords)
 
-        return np.divide(self.coords[idx, :] - min_coord, max_coord-min_coord)
+        return np.divide(self.coords[idx, :] - min_coord, max_coord - min_coord)
 
 
 class PointMap:
@@ -68,10 +66,10 @@ def delta_energy_WRONG(self, a, b):
         test_map[b] = self.map[a]
 
         energy_before = np.sum(np.multiply(self.source.dist[a, :], self.dest.dist[a_dest, :][test_map])) \
-            + np.sum(np.multiply(self.source.dist[b, :], self.dest.dist[b_dest, :][test_map]))
+                        + np.sum(np.multiply(self.source.dist[b, :], self.dest.dist[b_dest, :][test_map]))
 
         energy_after = np.sum(np.multiply(self.source.dist[a, :], self.dest.dist[b_dest, :][test_map])) \
-            + np.sum(np.multiply(self.source.dist[b, :], self.dest.dist[a_dest, :][test_map]))
+                       + np.sum(np.multiply(self.source.dist[b, :], self.dest.dist[a_dest, :][test_map]))
 
         return energy_after - energy_before
 
@@ -106,7 +104,6 @@ def iterate(self, n_iter):
             p_swap = 1 / (1 + np.exp(4 * energy_change / self.start_energy * 100))
             print(f"{idx}/{n_iter}  energy = {self.energy()}, p_swap = {p_swap}")
             if px < p_swap:
-
                 # Swap the two if energy
                 old_a = self.map[a]
                 self.map[a] = self.map[b]
@@ -147,4 +144,5 @@ def plot_map(self):
     pm.iterate(10000)
 
     import pdb
-    pdb.set_trace()
\ No newline at end of file
+
+    pdb.set_trace()
diff --git a/snudda/place/region_mesh.py b/snudda/place/region_mesh.py
index ed3f2d3f2..e00241749 100644
--- a/snudda/place/region_mesh.py
+++ b/snudda/place/region_mesh.py
@@ -1,17 +1,16 @@
+import os
+import pickle
+import re
 import sys
+import timeit
 
 import numpy as np
 import scipy
-from scipy import ndimage
 from numba import jit
-import re
-import os
-import pickle
-import timeit
+from scipy import ndimage
 
 
 class RegionMesh(object):
-
     """ Handles neuron placement within a 3D mesh. """
 
     def __init__(self, filename, d_view=None, role="master",
@@ -114,8 +113,8 @@ def __init__(self, filename, d_view=None, role="master",
         self.next_neuron_type = 1
         self.reject_ctr = None
 
-        # Used or set by setup_voxel_list
-        self.max_neurons_voxel = int(np.ceil(300000*(self.bin_width/1e-3)**3))  # We assume no more than 300k neurons per mm3
+        # Used or set by setup_voxel_list, we assume no more than 300k neurons per mm3
+        self.max_neurons_per_voxel = int(np.ceil(300000 * (self.bin_width / 1e-3) ** 3))
         self.voxel_next_neuron = None
         self.voxel_neurons = None
 
@@ -232,10 +231,10 @@ def setup_parallel(self, d_view=None):
         self.write_log("Setting up parallel")
 
         assert self.role == "master", \
-            "setupParallel should only be called by master"
+            "setup_parallel should only be called by master"
 
         if self.workers_initialised:
-            self.write_log("setupParallel: workers already initialised")
+            self.write_log("setup_parallel: workers already initialised")
             return
 
         with d_view.sync_imports():
@@ -246,8 +245,7 @@ def setup_parallel(self, d_view=None):
             d_view.push({"filename": self.filename}, block=True)
 
             if self.logfile_name is not None:
-                engine_log_file = [self.logfile_name + "-"
-                                   + str(x) for x in range(0, len(d_view))]
+                engine_log_file = [f"{self.logfile_name}-{x}" for x in range(0, len(d_view))]
             else:
                 engine_log_file = [[] for x in range(0, len(d_view))]
 
@@ -262,9 +260,9 @@ def setup_parallel(self, d_view=None):
             import uuid
             import traceback
             tstr = traceback.format_exc()
-            tmp = open("save/tmp-striatum-mesh-log-file-" + str(uuid.uuid4()), 'w')
-            tmp.write("Exception: " + str(e))
-            tmp.write("Trace:" + tstr)
+            tmp = open(os.path.join("save", f"tmp-striatum-mesh-log-file-{uuid.uuid4()}"), 'w')
+            tmp.write(f"Exception: {e}")
+            tmp.write(f"Trace: {tstr}")
             tmp.close()
             self.write_log(tstr, is_error=True)
             import pdb
@@ -518,8 +516,8 @@ def setup_voxel_filter(self):
                 for m in inner_mask:
                     self.voxel_mask_inner = np.logical_or(self.voxel_mask_inner, m)
 
-        self.write_log(f"Fraction of border voxels: " 
-                       f"{np.sum(self.voxel_mask_border)/np.prod(self.voxel_mask_border.shape)}")
+        self.write_log(f"Fraction of border voxels: "
+                       f"{np.sum(self.voxel_mask_border) / np.prod(self.voxel_mask_border.shape)}")
 
         self.save_cache()
 
@@ -716,14 +714,6 @@ def ray_casting_helper(point,
 
         intersect_count = np.sum((0 <= r) * (r <= 1) * (0 <= s) * (s <= 1) * (0 <= t) * (s + t <= 1))
 
-        # print(f"{point} intersection count {intersect_count}")
-
-        # if np.random.uniform() < 0.05:
-        #     if (np.mod(intersect_count, 2) == 1) != self.ray_casting_OLD(point):
-        #         print(f"New function differs from old for point {point}... check why")
-        #         import pdb
-        #         pdb.set_trace()
-
         return np.mod(intersect_count, 2) == 1
 
     ############################################################################
@@ -805,7 +795,7 @@ def setup_voxel_list(self):
 
         self.voxel_next_neuron = np.zeros(self.num_bins, dtype=int)
         self.voxel_neurons = np.zeros((self.num_bins[0], self.num_bins[1],
-                                       self.num_bins[2], self.max_neurons_voxel, 3))
+                                       self.num_bins[2], self.max_neurons_per_voxel, 3))
 
     ############################################################################
 
@@ -1037,8 +1027,8 @@ def place_neurons(self, num_cells, neuron_type=None, d_min=None):
 
                 if self.voxel_next_neuron[vox_idx[0], vox_idx[1], vox_idx[2]] > 0:
                     tmp = self.voxel_neurons[vox_idx[0], vox_idx[1], vox_idx[2],
-                                             0:self.voxel_next_neuron[vox_idx[0], vox_idx[1], vox_idx[2]],
-                                             :] - putative_loc
+                          0:self.voxel_next_neuron[vox_idx[0], vox_idx[1], vox_idx[2]],
+                          :] - putative_loc
 
                     min_dist2 = min(min_dist2, np.min(np.sum(np.square(tmp), axis=1)))
 
@@ -1063,11 +1053,11 @@ def place_neurons(self, num_cells, neuron_type=None, d_min=None):
                 # lots of distance comparisons
                 try:
                     self.voxel_neurons[voxel_idx[0], voxel_idx[1], voxel_idx[2],
-                                       self.voxel_next_neuron[voxel_idx[0], voxel_idx[1], voxel_idx[2]], :] = putative_loc
+                    self.voxel_next_neuron[voxel_idx[0], voxel_idx[1], voxel_idx[2]], :] = putative_loc
                     self.voxel_next_neuron[voxel_idx[0], voxel_idx[1], voxel_idx[2]] += 1
                 except:
-                    self.write_log(f"If you see this error you probably need to increase " 
-                                   f"self.max_neurons_voxel={self.max_neurons_voxel}")
+                    self.write_log(f"If you see this error you probably need to increase "
+                                   f"self.max_neurons_voxel={self.max_neurons_per_voxel}")
                     import traceback
                     tstr = traceback.format_exc()
                     print(tstr)
@@ -1342,7 +1332,7 @@ def verify_d_min(self):
 
         xc = (self.neuron_coords[bad_idx, :] - self.min_coord) % self.bin_width
         ax.scatter(xc[:, 0], xc[:, 1], xc[:, 2], 'black')
-        plt.title("Bad neuron locations: " + str(xc.shape[0]))
+        plt.title(f"Bad neuron locations: {xc.shape[0]}")
         plt.axis('tight')
         plt.xlabel('X')
         plt.ylabel('Y')
@@ -1352,10 +1342,10 @@ def verify_d_min(self):
         plt.pause(0.001)
 
         try:
-            assert self.d_min <= np.min(min_dist), "dMin criteria not fulfilled: " \
-                                                  + str(np.min(min_dist)) + " < dMin = " + str(self.d_min)
+            assert self.d_min <= np.min(min_dist), \
+                f"d_min criteria not fulfilled: {np.min(min_dist)} < d_min = {self.d_min}"
         except:
-            self.write_log("dMin not fulfilled")
+            self.write_log(f"d_min criteria not fulfilled: {np.min(min_dist)} < d_min = {self.d_min}")
             import pdb
             pdb.set_trace()
 
@@ -1375,7 +1365,7 @@ def simple_test_case(self):
 
         for i in range(0, 1000):
             test_point = np.random.uniform(0, 1e-6, 3) \
-                        + np.array([0, 0, 0]) * 1e-6
+                         + np.array([0, 0, 0]) * 1e-6
 
             # testPoint = np.array([0.5,0.61,0.5])*1e-6
 
@@ -1437,11 +1427,11 @@ def inner_voxel_volume(self):
         rc = Client(profile=os.getenv('IPYTHON_PROFILE'),
                     # sshserver='127.0.0.1',
                     debug=False)
-        print('Client IDs: ' + str(rc.ids))
+        print(f"Client IDs: {rc.ids}")
 
         # http://davidmasad.com/blog/simulation-with-ipyparallel/
         # http://people.duke.edu/~ccc14/sta-663-2016/19C_IPyParallel.html
-        print("Client IDs: " + str(rc.ids))
+        print(f"Client IDs: {rc.ids}")
         d_view = rc.direct_view(targets='all')  # rc[:] # Direct view into clients
     else:
         print("No IPYTHON_PROFILE enviroment variable set, running in serial")
@@ -1460,9 +1450,9 @@ def inner_voxel_volume(self):
     nNeurons = 1730000
     neuronPos = sm.place_neurons(nNeurons)
     # sm.verify_d_min()
-    sm.plot_neurons(pdf_name="figures/striatum-fig-somas.png")
+    sm.plot_neurons(pdf_name=os.path.join("figures", "striatum-fig-somas.png"))
 
-    sm.plot_struct(pdf_name="figures/striatum-fig-struct.png")
+    sm.plot_struct(pdf_name=os.path.join("figures", "striatum-fig-struct.png"))
 
     # sm.testPlot()
     # sm.testPlotCached()
diff --git a/snudda/place/rotation.py b/snudda/place/rotation.py
index 175c856e8..85ae5a948 100644
--- a/snudda/place/rotation.py
+++ b/snudda/place/rotation.py
@@ -1,14 +1,13 @@
+import json
 from collections import OrderedDict
 
 import numpy as np
-import json
 from scipy.interpolate import griddata
 
 from snudda.neurons.neuron_morphology import NeuronMorphology
 
 
 class SnuddaRotate:
-
     """ Rotation object. """
 
     def __init__(self, config_file=None):
@@ -51,7 +50,7 @@ def parse_config_file(self, config_file):
     @staticmethod
     def random_z_rotate(rng):
         """ Helper method, rotate around z-axis (of SWC coordinates)"""
-        ang = 2*np.pi*rng.uniform()
+        ang = 2 * np.pi * rng.uniform()
 
         return np.array([[np.cos(ang), -np.sin(ang), 0],
                          [np.sin(ang), np.cos(ang), 0],
@@ -66,7 +65,7 @@ def get_rotations(self, volume_name, neuron_type, neuron_positions, rng):
             rotation_mode, field_position, field_rotation = "random", None, None
 
         if not rotation_mode or rotation_mode.lower() == "none":
-            rotation_matrices = [np.eye]*neuron_positions.shape[0]
+            rotation_matrices = [np.eye] * neuron_positions.shape[0]
 
         elif rotation_mode in ["random", "default"]:
             rotation_matrices = [NeuronMorphology.rand_rotation_matrix(rand_nums=rng.random(size=(3,)))
@@ -137,7 +136,7 @@ def load_rotation_field(rotation_field_file, volume_name):
 
         if volume_name in rotation_field_data:
             assert "position" in rotation_field_data[volume_name] \
-                and "rotation" in rotation_field_data[volume_name], \
+                   and "rotation" in rotation_field_data[volume_name], \
                 f"Missing position and/or rotation tag in volume {volume_name}"
 
             return np.array(rotation_field_data[volume_name]["position"]) * 1e-6, \
diff --git a/snudda/place/volumetric_mapping.py b/snudda/place/volumetric_mapping.py
index 1925a6b00..c28abbfd0 100644
--- a/snudda/place/volumetric_mapping.py
+++ b/snudda/place/volumetric_mapping.py
@@ -6,55 +6,58 @@
 @author: wst
 """
 
+import json
 import os
+
 import numpy as np
-import json
 from scipy.spatial.distance import pdist, squareform
+
 from snudda.place.region_mesh import RegionMesh
 
+
 class VolumetricMap:
-    
-    def __init__(self, meshfile_a, meshfile_b, n = 100, inversion = False, initial = True, predefined_points = None):
+
+    def __init__(self, meshfile_a, meshfile_b, n=100, inversion=False, initial=True, predefined_points=None):
         self.meshfile_a = meshfile_a
         self.meshfile_b = meshfile_b
         self.n = n
         self.inversion = inversion
         self.initial = initial
-        
-        if predefined_points:                                    #user defined nested list of points to map between                    
+
+        if predefined_points:  # user defined nested list of points to map between
             self.a_points = np.array(predefined_points[0])
             self.b_points = np.array(predefined_points[1])
-        else:                                                   #highjack RegionMesh to sample the volume
+        else:  # highjack RegionMesh to sample the volume
             self.a = RegionMesh(meshfile_a)
             self.b = RegionMesh(meshfile_b)
             self.a_points = self.a.place_neurons(self.n)
             self.b_points = self.b.place_neurons(self.n)
-            
+
     def distance(self, coords):
-        
+
         return squareform(pdist(coords))
-        
+
     def initial_map(self):
-        
+
         bcopy = self.b_points.copy()
-        if self.inversion:                                              #invert ventrodorsal 
-            bcopy[:,2]*= -1
-            
+        if self.inversion:  # invert ventrodorsal
+            bcopy[:, 2] *= -1
+
         mapping = []
         for i in range(len(self.a_points)):
-            j= np.linalg.norm(self.a_points[i] - bcopy, axis = 1).argmin()
-            k = np.argwhere(self.b_points == bcopy[j])[0,0]
+            j = np.linalg.norm(self.a_points[i] - bcopy, axis=1).argmin()
+            k = np.argwhere(self.b_points == bcopy[j])[0, 0]
             mapping.append(k)
-            bcopy = np.delete(bcopy, j, axis = 0)
-            
+            bcopy = np.delete(bcopy, j, axis=0)
+
         return mapping
-    
+
     def energy(self, mapping):
-        
+
         a_dist = self.distance(self.a_points)
-        if self.inversion:  #invert ventrodorsal topography
-            inverted_points = self.b_points.copy() 
-            inverted_points[:,2]*= -1
+        if self.inversion:  # invert ventrodorsal topography
+            inverted_points = self.b_points.copy()
+            inverted_points[:, 2] *= -1
             # inverted_points[:,1]*= 1
             b_dist = self.distance(inverted_points)
         else:
@@ -63,119 +66,116 @@ def energy(self, mapping):
         return np.sum(np.power(a_dist - b_dist[:, mapping][mapping, :], 2))
 
     def optimize_map(self, n_iter):
-        
+
         if self.initial:
             self.mapping = self.initial_map()
         else:
-            self.mapping = np.arange(0,len(self.a_points) ,1)
-            
-        history = []                                                        #track optimization
+            self.mapping = np.arange(0, len(self.a_points), 1)
+
+        history = []  # track optimization
         e1 = self.energy(self.mapping)
         e = e1
         history.append(e)
-        
-        m = np.random.randint(low=0, high=self.n, size=(n_iter, 2)) 
+
+        m = np.random.randint(low=0, high=self.n, size=(n_iter, 2))
         p_val = np.random.uniform(size=n_iter)
 
-        for i, ((m1,m2), px) in enumerate(zip(m, p_val)):
-            
+        for i, ((m1, m2), px) in enumerate(zip(m, p_val)):
+
             new = self.mapping.copy()
             new[m1] = self.mapping[m2]
             new[m2] = self.mapping[m1]
             e_new = self.energy(new)
             e_change = e_new - e
-            
+
             p_swap = 1 / (1 + np.exp(50 * e_change / e1 * 100))
-            
+
             if px < p_swap:
                 self.mapping = new
                 e = e_new
             history.append(e)
-            
+
         self.opt_history = np.array(history)
         self.a_points = self.a_points
         self.b_points = self.b_points[self.mapping]
-        
-        return 
-    
+
+        return
+
     def plot_energy(self):
-        
+
         import matplotlib.pyplot as plt
         if self.opt_history is None:
             self.optimize_map(1000)
-            
+
         fig, ax = plt.subplots()
         ax.plot(self.opt_history)
         ax.set_xlabel('Iterations')
         ax.set_ylabel('Energy')
-        title = '{} points, {} iterations'.format(self.n, len(self.opt_history) -1)
+        title = '{} points, {} iterations'.format(self.n, len(self.opt_history) - 1)
         ax.set_title(title)
-        
+
         return
-    
+
     def get_colour(self, coords, idx):
         min_coord = np.min(coords)
         max_coord = np.max(coords)
 
-        return np.divide(coords[idx, :] - min_coord, max_coord-min_coord)
+        return np.divide(coords[idx, :] - min_coord, max_coord - min_coord)
+
+    def visualize_map(self, lines=True, points=True):
 
-    def visualize_map(self, lines = True, points = True):
-            
         import trimesh
         from vedo import embedWindow
-        embedWindow(backend = False) 
+        embedWindow(backend=False)
         from vedo import Mesh
         from vedo import Line
         import brainrender
         brainrender.settings.SHADER_STYLE = 'plastic'
         brainrender.settings.SHOW_AXES = False
         from brainrender.scene import Scene
-        
+
         a_tri = trimesh.load_mesh(self.meshfile_a)
         b_tri = trimesh.load_mesh(self.meshfile_b)
-        
-        scene = Scene(root = True)
+
+        scene = Scene(root=True)
         scene.jupyter = True
-        
-        scene.add(Mesh(a_tri, c = 'red', alpha = 0.1))
-        scene.add(Mesh(b_tri, c = 'blue', alpha = 0.1))
+
+        scene.add(Mesh(a_tri, c='red', alpha=0.1))
+        scene.add(Mesh(b_tri, c='blue', alpha=0.1))
 
         if lines:
             for i in range(self.n):
                 col = self.get_colour(self.a_points[:], i)
-                scene.add(Line(self.a_points[i,:]*1e6,self.b_points[i,:]*1e6, lw= 2.5, c = col))
+                scene.add(Line(self.a_points[i, :] * 1e6, self.b_points[i, :] * 1e6, lw=2.5, c=col))
         if points:
             for i in range(self.n):
                 col = self.get_colour(self.a_points[:], i)
-                scene.add(Point(self.a_points[i,:]*1e6, radius= 25, color = col, alpha = 0.4))
-                scene.add(Point(self.b_points[i,:]*1e6, radius= 25, color = col, alpha = 0.4))
+                scene.add(Point(self.a_points[i, :] * 1e6, radius=25, color=col, alpha=0.4))
+                scene.add(Point(self.b_points[i, :] * 1e6, radius=25, color=col, alpha=0.4))
+
+        scene.slice(scene.atlas.get_plane(norm=[0, 0, 1], sx=15000, sy=15000), close_actors=False)
+        scene.render(camera='top')
 
-        scene.slice(scene.atlas.get_plane(norm = [0, 0, 1], sx=15000, sy=15000), close_actors=False)
-        scene.render(camera = 'top')
-        
         return
-    
+
     def write_json(self, projection_name, outfile):
-        
-        mapping ={projection_name: {'source': self.a_points.tolist(), 'destination': self.b_points.tolist()}}
-        
+
+        mapping = {projection_name: {'source': self.a_points.tolist(), 'destination': self.b_points.tolist()}}
+
         with open(outfile, 'w+') as f:
-            json.dump(mapping, f, indent = 4)
-            
+            json.dump(mapping, f, indent=4)
+
         return
 
 
 if __name__ == "__main__":
-
     source_file = os.path.join("$SNUDDA_DATA", "mesh", "striatum-d.obj")
     target_file = os.path.join("$SNUDDA_DATA", "mesh", "SNr.obj")
     outfile = os.path.join("$SNUDDA_DATA", "projections", "direct.json")
     projection_name = 'DirectPathway'
-    
-    vm = VolumetricMap(source_file, target_file, n = 50, inversion = True)
+
+    vm = VolumetricMap(source_file, target_file, n=50, inversion=True)
     vm.optimize_map(10000)
     vm.plot_energy()
     vm.visualize_map()
-    vm.write_json(projection_name = projection_name, outfile = outfile )
-
-
+    vm.write_json(projection_name=projection_name, outfile=outfile)
diff --git a/snudda/plotting/Blender/visualisation/visualise_network.py b/snudda/plotting/Blender/visualisation/visualise_network.py
index 8115b834d..34dca5c5a 100644
--- a/snudda/plotting/Blender/visualisation/visualise_network.py
+++ b/snudda/plotting/Blender/visualisation/visualise_network.py
@@ -280,9 +280,9 @@ def visualise(self,
                         # Draw this neuron (the SWC import scales from micrometers to mm), the
                         # positions in the simulation are in meters, need to scale it to mm for
                         # blender to have same units.
-                        x = (origo[0] + voxel_size * syn[2]) * scale
-                        y = (origo[1] + voxel_size * syn[3]) * scale
-                        z = (origo[2] + voxel_size * syn[4]) * scale
+                        x = (origo[0] + voxel_size * syn[2]) * self.scale_f
+                        y = (origo[1] + voxel_size * syn[3]) * self.scale_f
+                        z = (origo[2] + voxel_size * syn[4]) * self.scale_f
 
                         if synapse_obj:
                             obj = synapse_obj.copy()
diff --git a/snudda/plotting/plotLTSdensity.py b/snudda/plotting/plotLTSdensity.py
index 3217d0a5f..fa3a80585 100644
--- a/snudda/plotting/plotLTSdensity.py
+++ b/snudda/plotting/plotLTSdensity.py
@@ -1,112 +1,103 @@
 import numpy as np
 
-
-
 # fileName = "morphology/network/v7/LTS-20190212/LTS_papercorrected_savedcorrected_axon.swc"
-fileName = "cellspecs/lts/LTS_Experiment-9862_20181211/Experiment-9862corrected-cor-rep.swc-withAxon"
+file_name = "cellspecs/lts/LTS_Experiment-9862_20181211/Experiment-9862corrected-cor-rep.swc-withAxon"
 
 # Load SWC file
-with open(fileName,"r") as f:
-  swcLines = f.readlines()    
+with open(file_name, "r") as f:
+    swcLines = f.readlines()
 
 binWidth = 10e-6
 dendArborHist = np.zeros((100,))
-radius = np.arange(0,dendArborHist.shape[0])*binWidth + binWidth/2
-  
+radius = np.arange(0, dendArborHist.shape[0]) * binWidth + binWidth / 2
 
-swcVals = np.zeros(shape=(len(swcLines),7))
+swcVals = np.zeros(shape=(len(swcLines), 7))
 
-comp_type = { 1: "soma", 2: "axon", 3: "dend", 4: "apic" }
+comp_type = {1: "soma", 2: "axon", 3: "dend", 4: "apic"}
 
 # Parse morphology
 nComps = 0
 for line in swcLines:
-  if(line[0] != "#"):
-    swcVals[nComps,:] = [float(s) for s in line.split()]
-    nComps += 1
+    if (line[0] != "#"):
+        swcVals[nComps, :] = [float(s) for s in line.split()]
+        nComps += 1
+
+swcVals = swcVals[:nComps, :]
 
-swcVals = swcVals[:nComps,:]
-    
 # Subtract 1 from ID and parentID, so we get easier indexing
-swcVals[:,0] -= 1
-swcVals[:,6] -= 1
+swcVals[:, 0] -= 1
+swcVals[:, 6] -= 1
 
-swcVals[:,2:6] *= 1e-6 # Convert to meter x,y,z, radie
+swcVals[:, 2:6] *= 1e-6  # Convert to meter x,y,z, radie
 
 # Plot neuron
 import matplotlib.pyplot as plt
-from mpl_toolkits.mplot3d import Axes3D
 
 fig = plt.figure()
 ax = fig.add_subplot(111, projection='3d')
 
-#plt.plot(swcVals[:,2],swcVals[:,3],swcVals[:,4],'*')
+# plt.plot(swcVals[:,2],swcVals[:,3],swcVals[:,4],'*')
 
-assert swcVals[0,1] == 1, "First row should be soma"
+assert swcVals[0, 1] == 1, "First row should be soma"
 
-somaCoord = swcVals[0,2:5]
+somaCoord = swcVals[0, 2:5]
 
 for row in swcVals:
-  if row[1] == 2:
-    col = "r"
-  elif(row[1] in [3,4]):
-    col = "b"
-  else:
-    continue
-    
-  parentCoords = swcVals[int(row[6]),2:5] - somaCoord
-  coords = row[2:5] - somaCoord
-  centre = (coords + parentCoords) / 2.0
-    
-  plt.plot([coords[0],parentCoords[0]],
-           [coords[1],parentCoords[1]],
-           [coords[2],parentCoords[2]], col + '-')
-
-
+    if row[1] == 2:
+        col = "r"
+    elif (row[1] in [3, 4]):
+        col = "b"
+    else:
+        continue
 
+    parentCoords = swcVals[int(row[6]), 2:5] - somaCoord
+    coords = row[2:5] - somaCoord
+    centre = (coords + parentCoords) / 2.0
 
+    plt.plot([coords[0], parentCoords[0]],
+             [coords[1], parentCoords[1]],
+             [coords[2], parentCoords[2]], col + '-')
 
 ########################################################################
 
 nPoints = 100000
-rng = [-100e-6,1500e-6,-200e-6,200e-6,-200e-6,200e-6]
+rng = [-100e-6, 1500e-6, -200e-6, 200e-6, -200e-6, 200e-6]
 
-x = rng[0] + (rng[1] - rng[0]) * np.random.rand(nPoints,1)
-y = rng[2] + (rng[3] - rng[2]) * np.random.rand(nPoints,1)
-z = rng[4] + (rng[5] - rng[4]) * np.random.rand(nPoints,1)
+x = rng[0] + (rng[1] - rng[0]) * np.random.rand(nPoints, 1)
+y = rng[2] + (rng[3] - rng[2]) * np.random.rand(nPoints, 1)
+z = rng[4] + (rng[5] - rng[4]) * np.random.rand(nPoints, 1)
 
-x1 = 200e-6 # Inner bump
-xw1 = 100e-6 #100e-6
-x2 = 300e-6 # Tube
+x1 = 200e-6  # Inner bump
+xw1 = 100e-6  # 100e-6
+x2 = 300e-6  # Tube
 xw2 = 300e-6
-x3 = 700e-6 # Outer bump
+x3 = 700e-6  # Outer bump
 xw3 = 100e-6
 
-Pkeep = 0.25*np.exp(-(((x-x1)/xw1)**2 + ((y-0)/50e-6)**2 + ((z-0)/30e-6)**2)) \
-    + 1*np.exp(-(((x-x2)/xw2)**2 + ((y-0)/15e-6)**2 + ((z-0)/10e-6)**2)) \
-+ 1*np.exp(-(((x-x3)/xw3)**2 + ((y-0)/15e-6)**2 + ((z-0)/15e-6)**2))
+Pkeep = 0.25 * np.exp(-(((x - x1) / xw1) ** 2 + ((y - 0) / 50e-6) ** 2 + ((z - 0) / 30e-6) ** 2)) \
+        + 1 * np.exp(-(((x - x2) / xw2) ** 2 + ((y - 0) / 15e-6) ** 2 + ((z - 0) / 10e-6) ** 2)) \
+        + 1 * np.exp(-(((x - x3) / xw3) ** 2 + ((y - 0) / 15e-6) ** 2 + ((z - 0) / 15e-6) ** 2))
 
 Pkeep = Pkeep / np.max(Pkeep)
 
-idx = np.where(Pkeep > np.random.rand(nPoints,1))[0]
+idx = np.where(Pkeep > np.random.rand(nPoints, 1))[0]
 xkeep = x[idx]
 ykeep = y[idx]
 zkeep = z[idx]
 
-dall = np.sqrt(xkeep**2 + ykeep**2 + zkeep**2)
+dall = np.sqrt(xkeep ** 2 + ykeep ** 2 + zkeep ** 2)
 
-#import matplotlib.pyplot as plt
-#from mpl_toolkits.mplot3d import Axes3D
+# import matplotlib.pyplot as plt
+# from mpl_toolkits.mplot3d import Axes3D
 
-#fig = plt.figure()
+# fig = plt.figure()
 # ax = fig.add_subplot(111, projection='3d')
 
-ax.scatter(0,0,0,'*',c="g")
-ax.scatter(xkeep,ykeep,zkeep,'*',c='k')
+ax.scatter(0, 0, 0, '*', c="g")
+ax.scatter(xkeep, ykeep, zkeep, '*', c='k')
 ax.set_aspect("equal")
 
-
-#ax.set_xlim([rng[0],rng[1]])
+# ax.set_xlim([rng[0],rng[1]])
 
 plt.ion()
 plt.show()
@@ -115,20 +106,18 @@
 
 # Read the data from Tepper
 tepperData = "DATA/Tepper2011extracted.csv"
-teppersholldata = np.genfromtxt(tepperData,delimiter=",")
-
-xsholl = teppersholldata[1:,0]
-axonsholl = teppersholldata[1:,1]
-dendsholl = teppersholldata[1:,2]
+teppersholldata = np.genfromtxt(tepperData, delimiter=",")
 
+xsholl = teppersholldata[1:, 0]
+axonsholl = teppersholldata[1:, 1]
+dendsholl = teppersholldata[1:, 2]
 
-
-fig,ax = plt.subplots()
+fig, ax = plt.subplots()
 ax.hist(dall)
-#plt.scatter(xsholl*1e-6, axonsholl,c="r")
+# plt.scatter(xsholl*1e-6, axonsholl,c="r")
 ax2 = ax.twinx()
 
-ax2.plot(xsholl*1e-6, axonsholl,"*",c="r")
+ax2.plot(xsholl * 1e-6, axonsholl, "*", c="r")
 ax.set_xlabel("Distance from soma")
 ax.set_ylabel("Axon count")
 ax2.set_ylabel("Axon sholl count")
@@ -139,4 +128,5 @@
 plt.savefig("figures/LTS-axon-density-tuning-histogram.png")
 
 import pdb
+
 pdb.set_trace()
diff --git a/snudda/plotting/plot_degeneration.py b/snudda/plotting/plot_degeneration.py
new file mode 100644
index 000000000..5f2456df7
--- /dev/null
+++ b/snudda/plotting/plot_degeneration.py
@@ -0,0 +1,52 @@
+import os
+import numpy as np
+from snudda.plotting.plot_input_locations import SnuddaPlotInputLocations
+
+
+class PlotDegeneration:
+
+    def __init__(self, original_network_path, degenerated_network_path):
+
+        self.original_plot = SnuddaPlotInputLocations(network_path=original_network_path)
+        self.degenerated_plot = SnuddaPlotInputLocations(network_path=degenerated_network_path)
+
+        self.fig_path = os.path.join(degenerated_network_path, "figures")
+        if not os.path.exists(self.fig_path):
+            os.mkdir(self.fig_path)
+
+    def plot_neuron(self, neuron_id):
+
+        ax = self.original_plot.plot_neuron_inputs(neuron_id=neuron_id,
+                                                   neuron_colour=np.array([0.6, 0.6, 0.6]),
+                                                   external_colour=np.array([1, 0.5, 0]),
+                                                   internal_colour=np.array([1, 0.5, 0]),
+                                                   size=1,
+                                                   save_fig=False, show_figure=False)
+        # ax = None
+        self.degenerated_plot.plot_neuron_inputs(neuron_id=neuron_id,
+                                                 neuron_colour=np.array([0, 0, 0]),
+                                                 ax=ax,
+                                                 size=50,
+                                                 save_fig=True, show_figure=True)
+
+        import matplotlib.pyplot as plt
+        plt.show()
+        plt.pause(10)
+
+
+def cli():
+
+    import argparse
+    parser = argparse.ArgumentParser("plot_degeneration")
+    parser.add_argument("original_network_path", help="Path to original network directory")
+    parser.add_argument("degenerated_network_path", help="Path to degenerated network directory")
+    parser.add_argument("neuron_id", help="Neuron ID to inspect", type=int)
+    args = parser.parse_args()
+
+    pd = PlotDegeneration(original_network_path=args.original_network_path,
+                          degenerated_network_path=args.degenerated_network_path)
+    pd.plot_neuron(neuron_id=args.neuron_id)
+
+
+if __name__ == "__main__":
+    cli()
diff --git a/snudda/plotting/plot_input_locations.py b/snudda/plotting/plot_input_locations.py
index f919e6610..77c14412d 100644
--- a/snudda/plotting/plot_input_locations.py
+++ b/snudda/plotting/plot_input_locations.py
@@ -11,10 +11,22 @@
 
 class SnuddaPlotInputLocations:
 
-    def __init__(self, network_path, input_file=None):
+    def __init__(self, network_path=None, network_file=None, input_file=None):
+
+        if not network_path:
+            if network_file:
+                network_path = os.path.dirname(network_file)
+            elif input_file:
+                network_path = os.path.dirname(input_file)
+            else:
+                network_path = "./"
 
         self.network_path = network_path
-        self.network_file = os.path.join(network_path, "network-synapses.hdf5")
+
+        if network_file is None:
+            self.network_file = os.path.join(network_path, "network-synapses.hdf5")
+        else:
+            self.network_file = network_file
 
         if input_file is None:
             self.input_file = os.path.join(network_path, "input-spikes.hdf5")
@@ -33,32 +45,46 @@ def __init__(self, network_path, input_file=None):
     def plot_neuron_inputs(self, neuron_id,
                            input_type=None,
                            show_internal_synapses=True,
-                           external_colour=None, internal_colour=None, size=10):
+                           external_colour=None, internal_colour=None,
+                           ax=None, neuron_colour=None,
+                           size=10,
+                           save_fig=True,
+                           dpi=300,
+                           show_figure=True):
 
         # TODO: Add ability to plot touch detected inputs also (use blue colour for them)
 
         coords = self.get_input_coords(neuron_id=neuron_id, input_type=input_type)
 
-        if not external_colour:
+        if external_colour is None:
             external_colour = "r"
 
-        if not internal_colour:
+        if internal_colour is None:
             internal_colour = "b"
 
-        
         nm = self.load_neuron(neuron_id=neuron_id)
-        fig = plt.figure()
-        ax = fig.add_subplot(111, projection='3d')
-        ax = nm.plot_neuron(soma_colour=[0, 0, 0], dend_colour=[0, 0, 0], plot_axon=False, plot_dendrite=True,show_plot=False,axis=ax)
+
+        if ax is None:
+            fig = plt.figure(visible=show_figure)
+            ax = fig.add_subplot(111, projection='3d')
+
+        if neuron_colour is None:
+            neuron_colour = np.array([0, 0, 0])
+
+        ax = nm.plot_neuron(soma_colour=neuron_colour, dend_colour=neuron_colour,
+                            plot_axon=False, plot_dendrite=True,
+                            show_plot=False, axis=ax)
 
         if len(coords) > 0:
             print(f"Plotting {len(coords)} external synapses")
            
-            ax.scatter(xs=coords[:, 0], ys=coords[:, 1], zs=coords[:, 2], c=external_colour, marker=".", s=size)
+            ax.scatter(xs=coords[:, 0], ys=coords[:, 1], zs=coords[:, 2],
+                       c=external_colour, marker=".", s=size)
 
         if show_internal_synapses:
             syn_coords = self.get_synapse_coords(neuron_id=neuron_id)
-            ax.scatter(xs=syn_coords[:, 0], ys=syn_coords[:, 1], zs=syn_coords[:, 2], c=internal_colour, marker=".")
+            ax.scatter(xs=syn_coords[:, 0], ys=syn_coords[:, 1], zs=syn_coords[:, 2],
+                       c=internal_colour, marker=".", s=size)
 
         neuron_name = self.snudda_load.data["neurons"][neuron_id]["name"]
 
@@ -80,8 +106,16 @@ def plot_neuron_inputs(self, neuron_id,
         if not os.path.exists(fig_path):
             os.mkdir(fig_path)
 
-        fig_name = os.path.join(fig_path, f_name)
-        plt.savefig(fig_name, dpi=300)
+        if save_fig:
+            fig_name = os.path.join(fig_path, f_name)
+            plt.savefig(fig_name, dpi=dpi)
+            print(f"Figure written: {fig_name}")
+
+        if show_figure:
+            fig = ax.get_figure()
+            fig.set_visible(show_figure)
+
+        return ax
 
     def get_input_locations(self, neuron_id, input_type=None):
 
@@ -131,10 +165,10 @@ def load_neuron(self, neuron_id):
 
         if neuron_id not in self.neuron_cache:
             neuron_info = self.snudda_load.data["neurons"][neuron_id]
-            nm = NeuronMorphology(name=neuron_info["name"],
-                                  swc_filename=neuron_info["morphology"],
-                                  position=neuron_info["position"],
-                                  rotation=neuron_info["rotation"])
+
+            np = NeuronPrototype(neuron_path=neuron_info["neuronPath"], neuron_name=neuron_info["name"])
+            nm = np.clone(parameter_key=neuron_info["parameterKey"], morphology_key=neuron_info["morphologyKey"],
+                          position=neuron_info["position"], rotation=neuron_info["rotation"])
             self.neuron_cache[neuron_id] = nm
 
         return self.neuron_cache[neuron_id]
@@ -144,18 +178,43 @@ def get_synapse_coords(self, neuron_id, pre_type=None):
         synapses, synapse_coords = self.snudda_load.find_synapses(post_id=neuron_id)
 
         assert (neuron_id == synapses[:, 1]).all(), f"Internal error, post_id should be {neuron_id} for all"
+
+        # Also get synapse coords from section id and section x
+        section_id = synapses[:, 9]
+        section_x = synapses[:, 10] * 1e-3
+
+        nm = self.load_neuron(neuron_id=neuron_id)
+        coords = np.zeros((len(section_id), 3))
+
+        for idx, (sec_id, sec_x) in enumerate(zip(section_id, section_x)):
+            coords[idx, :] = nm.get_section_coordinates(section_id=sec_id, section_x=sec_x)
+
+        dist = np.linalg.norm(coords - synapse_coords, axis=-1)
+        max_dist = 10e-6  # np.sqrt(3*(5e-6 ** 2))
+        assert (dist <= max_dist).all(), \
+            (f"Synapse coordinates mismatch {synapse_coords[np.where(dist > max_dist)[0], :]} "
+             f"vs {coords[np.where(dist > max_dist)[0], :]}"
+             f" (distances {dist[np.where(dist > max_dist)[0]]} with allowed max_dist = {max_dist})")
+
         pre_id = synapses[:, 0]
 
         if pre_type:
             pre_id_list = self.snudda_load.get_neuron_id_of_type(pre_type=pre_type)
 
-        return synapse_coords
+            keep_idx = []
+            for idx, pid in enumerate(pre_id):
+                if pid in pre_id_list:
+                    keep_idx.append(idx)
+
+            coords = coords[idx, :]
+
+        return coords
 
 
 def plot_input_location_cli():
 
     import argparse
-    parser = argparse.ArgumentParser("Plot input locations")
+    parser = argparse.ArgumentParser("plot_input_locations")
     parser.add_argument("networkPath", help="Path to network directory")
     parser.add_argument("neuronID", help="NeuronID to inspect", type=int)
     parser.add_argument("--inputType", help="Input type to show (default all)", default=None, type=str)
diff --git a/snudda/plotting/plot_spike_raster_v2.py b/snudda/plotting/plot_spike_raster_v2.py
index 1459d5fbf..db29c66f4 100644
--- a/snudda/plotting/plot_spike_raster_v2.py
+++ b/snudda/plotting/plot_spike_raster_v2.py
@@ -36,8 +36,8 @@ def __init__(self, network_path, network_file=None, simulation_file=None, figure
 
         self.spike_time = spike_data[:, 0]
         self.spike_neuron_id = spike_data[:, 1].astype(int)
-        #self.traces = self.snudda_simulation_load.get_voltage()
-        self.traces, self.time = self.snudda_simulation_load.get_voltage()
+        self.traces = self.snudda_simulation_load.get_voltage()
+        self.time = self.snudda_simulation_load.get_time()
 
     def make_figures_directory(self):
 
@@ -69,6 +69,7 @@ def get_all_colours(self):
             neuron_colours[idx, :] = self.get_colours(nt)
 
         return neuron_colours
+
     def plot_hist_raster(self, type_order=None, skip_time=0, end_time=None, fig_size=None, type_division=None):
         # type_division: divides plot in two parts based on neuron type.
         #   Example 1: [["dspn","ispn"],["chin", "fsn","lts"]]
@@ -79,14 +80,15 @@ def plot_hist_raster(self, type_order=None, skip_time=0, end_time=None, fig_size
         neuron_type_list = self.snudda_load.get_neuron_types(return_set=False)
         neuron_type_map = dict()
         if end_time is None:
-            end_time=1.02*max(self.time)
+            end_time = 1.02 * max(self.time)
         if type_order is None:
-            unique_neuron_types = np.unique(neuron_type_list)#set(neuron_type_list)
+            unique_neuron_types = np.unique(neuron_type_list)
             type_order = unique_neuron_types
         else:
             unique_neuron_types = type_order + list(set(neuron_type_list) - set(type_order))
-        if type_division==None:
-            type_division=[unique_neuron_types,[]]
+
+        if type_division is None:
+            type_division = [unique_neuron_types, []]
 
         for nt_idx, nt in enumerate(unique_neuron_types):
             neuron_type_map[nt] = nt_idx
@@ -104,7 +106,7 @@ def plot_hist_raster(self, type_order=None, skip_time=0, end_time=None, fig_size
         for t in type_order:
             type_dict[t] = [i for i, x in enumerate(neuron_type_list) if x.lower() == t.lower()]
 
-        #Prepare figure
+        # Prepare figure
         if not fig_size:
             fig_size = (10, 10)
         fig = plt.figure(figsize=fig_size)
@@ -126,37 +128,38 @@ def plot_hist_raster(self, type_order=None, skip_time=0, end_time=None, fig_size
         sc = np.zeros((len(spike_y), 3))
         for i in range(0, 3):
             sc[:, i] = np.take(colour_lookup[:, i], self.spike_neuron_id)
-        ax.scatter(self.spike_time-skip_time, spike_y, color=sc, s=5, linewidths=0.1)
+        ax.scatter(self.spike_time - skip_time, spike_y, color=sc, s=5, linewidths=0.1)
 
-        spike_count = []
         max0 = 0
         max1 = 0
         spike2type = np.take(neuron_type_list, self.spike_neuron_id)
 
-        #Spike rates
+        # Spike rates
         for t in type_order:
-            cellSpikeRates=np.array([])
-            spikesOfType=[i for i, x in enumerate(spike2type) if x.lower() == t.lower()]
-            pruned_spikes = self.spike_time[spikesOfType] - skip_time
+            cell_spike_rates = np.array([])
+            spikes_of_type = [i for i, x in enumerate(spike2type) if x.lower() == t.lower()]
+            pruned_spikes = self.spike_time[spikes_of_type] - skip_time
             pruned_spikes = pruned_spikes[pruned_spikes > 0]
-            spike_y_t=spike_y[spikesOfType]
-            spike_y_t=spike_y_t[pruned_spikes > 0]
-            uspike_y_t=np.unique(spike_y_t)
+            spike_y_t = spike_y[spikes_of_type]
+            spike_y_t = spike_y_t[pruned_spikes > 0]
+            uspike_y_t = np.unique(spike_y_t)
+
             for cellid in uspike_y_t:
-                cellSpikeRate=len(pruned_spikes[cellid==spike_y_t])/(end_time - skip_time)
-                cellSpikeRates=np.append(cellSpikeRates,cellSpikeRate)
+                cell_spike_rate = len(pruned_spikes[cellid == spike_y_t]) / (end_time - skip_time)
+                cell_spike_rates = np.append(cell_spike_rates, cell_spike_rate)
             num_of_type = len(type_dict[t])
-            cellSpikeRates=np.append(cellSpikeRates,np.zeros(num_of_type - len(cellSpikeRates)))
-            #print("Mean: {0}Hz, Stdev: {1}Hz {2} {3}".format(t,np.mean(cellSpikeRates),np.std(cellSpikeRates),cellSpikeRates))
-            print("NeuronType: {0}, Mean: {1}Hz Stdev: {2}Hz".format(t, np.mean(cellSpikeRates), np.std(cellSpikeRates)))
+            cell_spike_rates = np.append(cell_spike_rates, np.zeros(num_of_type - len(cell_spike_rates)))
+
+            print("NeuronType: {0}, Mean: {1}Hz Stdev: {2}Hz".format(t, np.mean(cell_spike_rates),
+                                                                     np.std(cell_spike_rates)))
 
         # histogram
         for t in type_order:
-            spikesOfType=[i for i, x in enumerate(spike2type) if x.lower() == t.lower()]
-            pruned_spikes = self.spike_time[spikesOfType] - skip_time
+            spikes_of_type = [i for i, x in enumerate(spike2type) if x.lower() == t.lower()]
+            pruned_spikes = self.spike_time[spikes_of_type] - skip_time
             pruned_spikes = pruned_spikes[pruned_spikes > 0]
-            num_of_type = len(type_dict[t])#
-            nspikes=len(pruned_spikes)
+            num_of_type = len(type_dict[t])  #
+            nspikes = len(pruned_spikes)
             bin_width = 0.05  # 10  # ms
             bin_range = np.arange(0, end_time + skip_time + bin_width, bin_width)
             if (nspikes > 0) & (t.lower() in type_division[0]):
@@ -164,25 +167,25 @@ def plot_hist_raster(self, type_order=None, skip_time=0, end_time=None, fig_size
                                                   bins=bin_range,
                                                   range=(skip_time, end_time),
                                                   density=0,
-                                                  color=sc[spikesOfType][0],
+                                                  color=sc[spikes_of_type][0],
                                                   alpha=1.0,
                                                   histtype='step',
                                                   weights=np.ones_like(pruned_spikes) / bin_width / num_of_type)
-                #spike_count.append((t, len(pruned_spikes), num_of_type))
+
                 max0 = max(np.append(counts0, max0))
             elif (nspikes > 0) & (t.lower() in type_division[1]):
                 counts1, bins1, bars1 = atop2.hist(pruned_spikes,
                                                    bins=bin_range,
                                                    range=(skip_time, end_time),
                                                    density=0,
-                                                   color=sc[spike2type==t][0],
+                                                   color=sc[spike2type == t][0],
                                                    alpha=1.0,
                                                    histtype='step',
                                                    weights=np.ones_like(pruned_spikes) / bin_width / num_of_type)
-                #spike_count.append((t, len(pruned_spikes), num_of_type))
+
                 max1 = max(np.append(counts1, max1))
-            spikeRate=len(pruned_spikes) / num_of_type / (end_time - skip_time)
-            print("{0}: {1} Hz".format(t,spikeRate))
+            spike_rate = len(pruned_spikes) / num_of_type / (end_time - skip_time)
+            print("{0}: {1} Hz".format(t, spike_rate))
         # Get position of labels
         unique_neuron_types = set(neuron_type_list)
         y_tick = []
@@ -198,9 +201,9 @@ def plot_hist_raster(self, type_order=None, skip_time=0, end_time=None, fig_size
 
         if skip_time or end_time:
             x_lim = ax.get_xlim()
-            x_lim = (0,x_lim[1])
+            x_lim = (0, x_lim[1])
             if end_time:
-                x_lim = (x_lim[0],end_time)
+                x_lim = (x_lim[0], end_time)
             ax.set_xlim(x_lim)
         atop.set_xlim(x_lim)
         atop2.set_xlim(x_lim)
@@ -249,7 +252,7 @@ def plot_spike_raster(self, type_order=None, skip_time=0, end_time=None, fig_siz
         for i in range(0, 3):
             sc[:, i] = np.take(colour_lookup[:, i], self.spike_neuron_id)
 
-        ax.scatter(self.spike_time-skip_time, spike_y, color=sc, s=5, linewidths=0.1)
+        ax.scatter(self.spike_time - skip_time, spike_y, color=sc, s=5, linewidths=0.1)
 
         # Get position of labels
         unique_neuron_types = set(neuron_type_list)
@@ -281,7 +284,6 @@ def plot_spike_raster(self, type_order=None, skip_time=0, end_time=None, fig_siz
 
 
 if __name__ == "__main__":
-
     from argparse import ArgumentParser
 
     parser = ArgumentParser("Scatter plot")
diff --git a/snudda/simulate/model_current_injections.py b/snudda/simulate/model_current_injections.py
index b8e1f4f0b..163c0c4cf 100644
--- a/snudda/simulate/model_current_injections.py
+++ b/snudda/simulate/model_current_injections.py
@@ -29,17 +29,14 @@
 import os
 import sys
 
-from snudda.simulate.simulate import SnuddaSimulate
-from snudda.utils.load import SnuddaLoad
-from snudda.init.init import SnuddaInit
-from snudda import Snudda
-
-import numpy as np
-
 import matplotlib
 import matplotlib.pyplot as plt
+import numpy as np
 
-import neuron
+from snudda import Snudda
+from snudda.init.init import SnuddaInit
+from snudda.simulate.simulate import SnuddaSimulate
+from snudda.utils.load import SnuddaLoad
 
 
 class SnuddaModelCurrentInjections(object):
diff --git a/snudda/simulate/network_pair_pulse_simulation.py b/snudda/simulate/network_pair_pulse_simulation.py
index 77413d8fe..70f2d100f 100644
--- a/snudda/simulate/network_pair_pulse_simulation.py
+++ b/snudda/simulate/network_pair_pulse_simulation.py
@@ -48,17 +48,16 @@
 # since both voltages are recorded
 
 import os
-import glob
 import sys
 
-import numpy as np
-from snudda.simulate.simulate import SnuddaSimulate
-from snudda.utils.load import SnuddaLoad
-from snudda.utils import SnuddaLoadNetworkSimulation
-
 import matplotlib
 import matplotlib.pyplot as plt
 import neuron
+import numpy as np
+
+from snudda.simulate.simulate import SnuddaSimulate
+from snudda.utils import SnuddaLoadNetworkSimulation
+from snudda.utils.load import SnuddaLoad
 
 
 # We want to match Taverna 2008 data:
@@ -127,9 +126,9 @@ def __init__(self, network_path,
         # self.volt_file_alt_mask = os.path.join(self.network_path,
         #                                        f"synapse-calibration-volt-{self.pre_type}-*.txt")
 
-        self.snudda_sim = None   # Defined in run_sim
+        self.snudda_sim = None  # Defined in run_sim
         self.snudda_load = None  # Defined in analyse
-        self.data = None         # Defind in analyse
+        self.data = None  # Defind in analyse
         self.holding_i_clamp_list = []
         self.pre_id = []
         self.possible_post_id = []
diff --git a/snudda/simulate/nrn_simulator_parallel.py b/snudda/simulate/nrn_simulator_parallel.py
index 05af6295b..a8c842537 100644
--- a/snudda/simulate/nrn_simulator_parallel.py
+++ b/snudda/simulate/nrn_simulator_parallel.py
@@ -28,8 +28,6 @@ def __init__(self, dt=None, cvode_active=False, cvode_minstep=None,
         self.pc = self.neuron.h.ParallelContext()
         self.pc.set_maxstep(10)
 
-
-
     def run(
             self,
             tstop=None,
diff --git a/snudda/simulate/pair_recording.py b/snudda/simulate/pair_recording.py
index 584ec05a0..bde7229ea 100644
--- a/snudda/simulate/pair_recording.py
+++ b/snudda/simulate/pair_recording.py
@@ -16,20 +16,20 @@
 #
 #
 
+import json
 import os
 from collections import OrderedDict
 
+import neuron
 import numpy as np
-import json
+
 from snudda.simulate import SnuddaSimulate
 from snudda.utils.save_network_recording import SnuddaSaveNetworkRecordings
 
-import neuron
 neuron.h.load_file("stdrun.hoc")
 
 
 class PairRecording(SnuddaSimulate):
-
     """ Runs simulation with current injections to one or more neurons. This code can be used to simulate
         a subset of the neurons, ie the neurons receiving current injections and their post synaptic targets.
 
@@ -54,7 +54,11 @@ def __init__(self, network_path, experiment_config_file):
         self.experiment_config_file = experiment_config_file
         self.experiment_config = self.read_experiment_config(experiment_config_file=experiment_config_file)
 
-        self.output_file_name = None
+        if "pairRecordingOutputFile" in self.experiment_config["meta"].keys():
+            self.output_file = os.path.join(self.network_path, "simulation",
+                                            self.experiment_config["meta"]["pairRecordingOutputFile"])
+        else:
+            self.output_file = os.path.join(self.network_path, "simulation", "output.hdf5")
 
         # Variables for synapse current recording
         self.synapse_currents = []
@@ -94,7 +98,7 @@ def parse_experiment_config(self):
         self.sim_duration = self.experiment_config["meta"]["simulationDuration"]
 
         if "pairRecordingOutputFile" in self.experiment_config["meta"]:
-            self.output_file_name = os.path.join(self.network_path, "simulation",
+            self.output_file = os.path.join(self.network_path, "simulation",
                                                  self.experiment_config["meta"]["pairRecordingOutputFile"])
 
         # Setup v_init for each neuron_id specified
@@ -124,7 +128,7 @@ def parse_experiment_config(self):
                                         end_times=stim_end_time, amplitudes=stim_amplitude)
 
         # Add voltage recordings to neurons
-        self.add_volt_recording()
+        self.add_volt_recording_all()
 
     @staticmethod
     def to_list(val, new_list_len=1):
@@ -138,7 +142,7 @@ def to_list(val, new_list_len=1):
         """
 
         if type(val) not in [list, np.ndarray, range]:
-            val = [val]*new_list_len
+            val = [val] * new_list_len
 
         return val
 
@@ -235,8 +239,10 @@ def set_neurons_to_simulate(self, selection=None):
             sim_id = pre_id
 
             for pid in pre_id:
-                post_id = set(self.snudda_loader.find_synapses(pre_id=pid)[0][:, 1])
-                sim_id = sim_id.union(post_id)
+                found_syn=self.snudda_loader.find_synapses(pre_id=pid)[0]
+                if found_syn is not None:
+                    post_id = set(found_syn[:, 1])
+                    sim_id = sim_id.union(post_id)
 
             self.simulate_neuron_ids = sorted(list(sim_id))
 
@@ -279,14 +285,13 @@ def run(self):
 
         # Write results to disk
         try:
-            save = SnuddaSaveNetworkRecordings(output_file=self.output_file_name)
-            save.write(t_save=self.t_save, v_save=self.v_save, v_key=self.v_key,
-                       t_spikes=self.t_spikes, id_spikes=self.id_spikes)
+            self.record.output_file = self.output_file
+            self.write_output()
 
-            pre_id = np.array([x[0] for x in self.synapse_currents])
-            post_id = np.array([x[1] for x in self.synapse_currents])
-            cur = [np.array(x[2]) for x in self.synapse_currents]
-            save.write_currents_OLD(t_save=self.t_save, i_save=cur, pre_id=pre_id, post_id=post_id)
+            # pre_id = np.array([x[0] for x in self.synapse_currents])
+            # post_id = np.array([x[1] for x in self.synapse_currents])
+            # cur = [np.array(x[2]) for x in self.synapse_currents]
+            # save.write_currents_OLD(t_save=self.t_save, i_save=cur, pre_id=pre_id, post_id=post_id)
 
         except:
             import traceback
@@ -301,7 +306,7 @@ def connect_neuron_synapses(self, start_row, end_row):
         """ Connects the synapses present in the synapse matrix between start_row and end_row-1. """
 
         source_id_list, dest_id, dend_sections, sec_id, sec_x, synapse_type_id, \
-            axon_distance, conductance, parameter_id = self.get_synapse_info(start_row=start_row, end_row=end_row)
+        axon_distance, conductance, parameter_id = self.get_synapse_info(start_row=start_row, end_row=end_row)
 
         for (src_id, section, section_x, s_type_id, axon_dist, cond, p_id) \
                 in zip(source_id_list, dend_sections, sec_x, synapse_type_id,
@@ -309,7 +314,9 @@ def connect_neuron_synapses(self, start_row, end_row):
 
             try:
                 syn = self.add_synapse(cell_id_source=src_id,
+                                       cell_id_dest=dest_id,
                                        dend_compartment=section,
+                                       section_id=sec_id,
                                        section_dist=section_x,
                                        synapse_type_id=s_type_id,
                                        axon_dist=axon_dist,
@@ -330,7 +337,7 @@ def connect_neuron_synapses(self, start_row, end_row):
 
     def plot_trace_overview(self):
         from snudda.plotting import PlotTraces
-        pt = PlotTraces(output_file=self.output_file_name,
+        pt = PlotTraces(output_file=self.output_file,
                         network_file=self.network_file)
 
         pt.plot_traces([x for x in pt.voltage])
@@ -343,11 +350,13 @@ def plot_traces(self, mark_current_y=-80.05e-3):
             cur_end = self.to_list(cur_info["end"])
             cur_times = list(zip(cur_start, cur_end))
 
-            skip_time = cur_start[0]/2
+            skip_time = cur_start[0] / 2
 
             assert type(pre_id) == int, f"Plot traces assumes one pre-synaptic neuron stimulated: {pre_id}"
-
-            post_id = set(self.snudda_loader.find_synapses(pre_id=pre_id)[0][:, 1])
+            if self.snudda_loader.find_synapses(pre_id=pre_id)[0] is None:
+                post_id =[]
+            else:
+                post_id = set(self.snudda_loader.find_synapses(pre_id=pre_id)[0][:, 1])
 
             for pid in post_id:
                 fig_name = f"Current-injection-pre-{pre_id}-post-{pid}.pdf"
@@ -364,13 +373,13 @@ def plot_trace(self, pre_id, post_id, offset=0, title=None, fig_name=None, skip_
             n_synapses = self.snudda_loader.find_synapses(pre_id=pre_id, post_id=post_id)[0].shape[0]
             title = f"{self.neurons[pre_id].name} -> {self.neurons[post_id].name} ({n_synapses} synapses)"
 
-        pt = PlotTraces(output_file=self.output_file_name, network_file=self.network_file)
+        pt = PlotTraces(output_file=self.output_file, network_file=self.network_file)
         fig = pt.plot_traces(trace_id=post_id, offset=offset, title=title, fig_name=fig_name, skip_time=skip_time)
 
         if mark_current:
             import matplotlib.pyplot as plt
             for t_start, t_end in mark_current:
-                plt.plot([t_start-skip_time, t_end-skip_time], [mark_current_y, mark_current_y], 'r-', linewidth=5)
+                plt.plot([t_start - skip_time, t_end - skip_time], [mark_current_y, mark_current_y], 'r-', linewidth=5)
 
     def mark_synapses_for_recording(self, pre_neuron_id, post_neuron_id):
 
@@ -391,4 +400,3 @@ def set_channel_rev(self, channel_name, v_rev):
         for syn in self.synapse_list:
             if channel_name == syn.hname().split("[")[0]:
                 syn.e = v_rev * 1e3
-
diff --git a/snudda/simulate/simulate.py b/snudda/simulate/simulate.py
index 06260d7ce..193ec8223 100644
--- a/snudda/simulate/simulate.py
+++ b/snudda/simulate/simulate.py
@@ -14,42 +14,34 @@
 #
 ############################################################################
 
+import json
+import os
+import re
+import timeit
 # Plot all sections
 # [neuron.h.psection(x) for x in neuron.h.allsec()]
 from collections import OrderedDict
 
-from mpi4py import MPI  # This must be imported before neuron, to run parallel
-from neuron import h  # , gui
-import neuron
-import bluepyopt.ephys as ephys
 import h5py
-import json
-import timeit
+import neuron
+import numpy as np
+from neuron import h  # , gui
 
-from snudda.utils.save_network_recording import SnuddaSaveNetworkRecordings
+import snudda.utils.memory
 from snudda.neurons.neuron_model_extended import NeuronModel
-# from Network_place_neurons import NetworkPlaceNeurons
-import numpy as np
 from snudda.simulate.nrn_simulator_parallel import NrnSimulatorParallel
-from snudda.utils.input_helper import to_list
+# If simulationConfig is set, those values override other values
+from snudda.utils.load import SnuddaLoad
+from snudda.utils.save_network_recording import SnuddaSaveNetworkRecordings
+from snudda.utils.snudda_path import snudda_parse_path
 
-import re
-import os
-
-import snudda.utils.memory
 
 # !!! Need to gracefully handle the situation where there are more workers than
 # number of neurons, currently we get problem when adding the voltage saving
-
 ##############################################################################
 
-# If simulationConfig is set, those values override other values
-from snudda.utils.load import SnuddaLoad
-from snudda.utils.snudda_path import snudda_parse_path
-
 
 class SnuddaSimulate(object):
-
     """ Simulate network """
 
     def __init__(self,
@@ -155,7 +147,7 @@ def __init__(self,
         # !!! different for AMPA and GABA?
         self.synapse_weight = 10.0  # microsiemens
         self.synapse_delay = 1  # ms
-        self.spike_threshold = -20   # TODO: Let each neuron type have individual spike threshold, based on what config file says.
+        self.spike_threshold = -20  # TODO: Let each neuron type have individual spike threshold, based on what config file says.
         self.axon_speed = 0.8  # Tepper and Lee 2007, Wilson 1986, Wilson 1990
         # refs taken from Damodaran et al 2013
 
@@ -177,8 +169,6 @@ def __init__(self,
         self.gap_junction_list = []
         self.external_stim = dict([])
         self.t_save = []
-        # self.v_save = []
-        # self.v_key = []
         self.i_save = []
         self.i_key = []
 
@@ -186,22 +176,19 @@ def __init__(self,
 
         self.gap_junction_next_gid = 0  # Are these gids separate from cell gids?
 
-        self.check_id_recordings = [] # Prevent segmentation fault due to garbage collection of spike id
+        self.check_id_recordings = []  # Prevent segmentation fault due to garbage collection of spike id
 
-        # Make sure the output dir exists, so we don't fail at end because we
-        # cant write file
+        # Make sure the output dir exists, so we don't fail at end because we cant write file
         self.create_dir(os.path.join("save", "traces"))
 
         self.conv_factor = {"tauR": 1e3,
                             "tauF": 1e3,
                             "tau": 1e3}
 
-        # self.writeLog(f"I am node {int(self.pc.id())}")
-
         # We need to initialise random streams, see Lytton el at 2016 (p2072)
 
         self.load_network_info(self.network_file)
-        
+
         self.record = SnuddaSaveNetworkRecordings(output_file=self.output_file, network_data=self.network_info)
         self.record.add_unit(data_type="voltage", target_unit="V", conversion_factor=1e-3)
         self.record.add_unit(data_type="synaptic_current", target_unit="A", conversion_factor=1e-9)
@@ -220,9 +207,6 @@ def setup(self):
         self.check_memory_status()
         self.pc.barrier()
 
-        #    for i in range(0,self.nNeurons):
-        #      print("Node : " + str(int(self.pc.id())) + " cell " + str(i) + " status " + str(self.pc.gid_exists(i)))
-
         self.connect_network()
         self.check_memory_status()
         self.pc.barrier()
@@ -321,11 +305,11 @@ def distribute_neurons(self):
         # TODO: Change to these ranges: range_borders = np.linspace(0, num_neurons, n_workers + 1).astype(int)
         #       will be faster, because of new numbering of neurons.
 
-        range_borders = np.linspace(0, self.num_neurons, self.pc.nhost()+1).astype(int)
+        range_borders = np.linspace(0, self.num_neurons, self.pc.nhost() + 1).astype(int)
         start_pos = range_borders[0]
         neuron_nodes = []
         for idx, end_pos in enumerate(range_borders[1:]):
-            neuron_nodes += [idx]*(end_pos - start_pos)
+            neuron_nodes += [idx] * (end_pos - start_pos)
             start_pos = end_pos
 
         self.neuron_nodes = neuron_nodes
@@ -420,8 +404,6 @@ def setup_neurons(self):
 
         self.write_log("Setup neurons")
 
-        # self.sim = ephys.simulators.NrnSimulator(cvode_active=False)
-        # self.sim = NrnSimulatorParallel()
         self.sim = NrnSimulatorParallel(cvode_active=False)
 
         # We need to load all the synapse parameters
@@ -510,16 +492,13 @@ def setup_neurons(self):
 
                 # !!! END OF DIRTY FIX
 
-                # !!! Connect a netcon and register it, taken from ballandstick's
-                #     connect2target function
+                # !!! Connect a netcon and register it, taken from ballandstick's connect2target function
                 nc = h.NetCon(self.neurons[ID].icell.axon[0](0.5)._ref_v,
                               None,
                               sec=self.neurons[ID].icell.axon[0])
                 nc.threshold = 10
 
                 self.pc.cell(ID, nc, 1)  # The 1 means broadcast spikes to other machines
-                # self.pc.outputcell(ID) # -- not needed, cell was called with a 1
-                # self.netConList.append(nc) -- Not needed according to Lytton et al 2016
 
                 # Record all spikes
                 t_spikes = h.Vector()
@@ -527,11 +506,7 @@ def setup_neurons(self):
 
                 self.pc.spike_record(ID, t_spikes, id_spikes)
                 self.check_id_recordings.append((ID, id_spikes))
-                self.record.register_compartment_data("spikes", neuron_id=ID, data=t_spikes,
-                                                      sec_id=-1, sec_x=0.5)
-
-
-                # self.pc.spike_record(ID, self.t_spikes, self.id_spikes)
+                self.record.register_compartment_data("spikes", neuron_id=ID, data=t_spikes, sec_id=-1, sec_x=0.5)
 
     ############################################################################
 
@@ -566,7 +541,6 @@ def connect_network_synapses(self):
 
         # This loops through all the synapses, and connects the relevant ones
         next_row = 0
-        # nextRowSet = [ fromRow, toRow ) -- ie range(fromRow,toRow)
         next_row_set = self.find_next_synapse_group(next_row)
 
         while next_row_set is not None:
@@ -579,15 +553,14 @@ def connect_network_synapses(self):
 
     ############################################################################
 
-    # This function starts at nextRow, then returns all synapses onto
-    # a neuron which is located on the worker
+    # This function starts at next_row, then returns all synapses onto a neuron which is located on the worker
 
     # This works for synapses, but it will not work for gap junctions, because
     # we need to connect the gap junctions from both sides
 
     # --- perhaps rewrite this as an iterator
 
-    def find_next_synapse_group(self, next_row=0, connection_type="synapses"):
+    def find_next_synapse_group(self, next_row=0):
 
         """
         Synapses are sorted by destination neuron (and then source neuron), this method starts from next_row
@@ -595,18 +568,9 @@ def find_next_synapse_group(self, next_row=0, connection_type="synapses"):
 
         Args:
             next_row (int): Row in the synapse matrix to start from
-            connection_type (str, optional): "synapses"
         """
 
-        if connection_type == "synapses":
-            synapses = self.synapses
-        elif connection_type == "gapjunctions":
-            # TODO: Remove gapJunction option? See comment above about gap junctions needing to be connected
-            #       from both sides.
-            assert False, "Remove the gapjunctions option here, as we are now using another method to find gap junctions"
-            synapses = self.gap_junctions
-        else:
-            assert False, "!!! find_next_synapse_group: Unknown connectionType: " + connection_type
+        synapses = self.synapses
 
         try:
             num_syn_rows = synapses.shape[0]
@@ -615,19 +579,19 @@ def find_next_synapse_group(self, next_row=0, connection_type="synapses"):
             tstr = traceback.format_exc()
             self.write_log(tstr, is_error=True)
 
-            assert False, ("find_next_synapse_group: If synapses was not loaded into memory, your problem is probably " 
+            assert False, ("find_next_synapse_group: If synapses was not loaded into memory, your problem is probably "
                            "that the HDF5 file that holds the synapses were closed. Sorry.")
 
         if next_row >= num_syn_rows:
             # No more synapses to get
             return None
 
-        # The synapse matrix is sorted on destID, ascending order
-        # We also assume that self.neuronID is sorted in ascending order
+        # The synapse matrix is sorted on dest_id, ascending order
+        # We also assume that self.neuron_id is sorted in ascending order
 
         start_row = None
         our_id = None
-        not_our_id = None
+        not_our_id = None  # used in the loop below, despite what pycharm thinks
 
         while start_row is None:
 
@@ -661,7 +625,8 @@ def find_next_synapse_group(self, next_row=0, connection_type="synapses"):
 
     ############################################################################
 
-    # Processing the range(startRow,endRow) (ie, to endRow-1)
+    # Processing the range(start_row,end_row) (ie, to end_row-1)
+
     def get_synapse_info(self, start_row, end_row):
 
         """
@@ -687,8 +652,7 @@ def get_synapse_info(self, start_row, end_row):
 
         # Double check mapping
         assert self.pc.gid2cell(dest_id) == self.neurons[dest_id].icell, \
-            "GID mismatch: " + str(self.pc.gid2cell(dest_id)) \
-            + " != " + str(self.neurons[dest_id].icell)
+            f"GID mismatch: {self.pc.gid2cell(dest_id)} != {self.neurons[dest_id].icell}"
 
         synapse_type_id = self.synapses[start_row:end_row, 6]
         axon_distance = self.synapses[start_row:end_row, 7]  # Obs in micrometers
@@ -697,23 +661,22 @@ def get_synapse_info(self, start_row, end_row):
         dend_sections = self.neurons[dest_id].map_id_to_compartment(sec_id)
         sec_x = self.synapses[start_row:end_row, 10] / 1000.0  # Convert to number 0-1
 
-        # conductances are stored in pS (because we use INTs),
-        # Neuron wants it in microsiemens??!
+        # Conductances are stored in pS (because we use INTs), NEURON wants it in microsiemens
         conductance = self.synapses[start_row:end_row, 11] * 1e-6
         parameter_id = self.synapses[start_row:end_row, 12]
-
         voxel_coords = self.synapses[start_row:end_row, 2:5]
+
         self.verify_synapse_placement(dend_sections, sec_x, dest_id, voxel_coords)
 
         return source_id_list, dest_id, dend_sections, sec_id, sec_x, synapse_type_id, \
-            axon_distance, conductance, parameter_id
+               axon_distance, conductance, parameter_id
 
     def connect_neuron_synapses(self, start_row, end_row):
 
         """ Connects the synapses present in the synapse matrix between start_row and end_row-1. """
 
         source_id_list, dest_id, dend_sections, sec_id, sec_x, synapse_type_id, \
-            axon_distance, conductance, parameter_id = self.get_synapse_info(start_row=start_row, end_row=end_row)
+        axon_distance, conductance, parameter_id = self.get_synapse_info(start_row=start_row, end_row=end_row)
 
         for (src_id, section, section_id, section_x, s_type_id, axon_dist, cond, p_id) \
                 in zip(source_id_list, dend_sections, sec_id, sec_x, synapse_type_id,
@@ -761,8 +724,7 @@ def find_local_gap_junctions(self):
                 cond: conductance
         """
 
-        # If the gap junction matrix is too large to fit in memory then
-        # this will need to be optimised
+        # If the gap junction matrix is too large to fit in memory then this will need to be optimised
 
         self.write_log("Finding node local gap junctions...")
 
@@ -772,7 +734,6 @@ def find_local_gap_junctions(self):
         gj_idx_a = np.where([x in self.neuron_id for x in self.gap_junctions[:, 0]])[0]
         gj_idx_b = np.where([x in self.neuron_id for x in self.gap_junctions[:, 1]])[0]
 
-        # GJIDoffset = self.network_info["GJIDoffset"]
         gj_id_offset = 100 * self.num_neurons
         gj_gid_src_a = gj_id_offset + 2 * gj_idx_a
         gj_gid_src_b = gj_id_offset + 2 * gj_idx_b + 1
@@ -798,11 +759,11 @@ def find_local_gap_junctions(self):
 
         # Merge the two lists together
 
-        gj_idx = np.concatenate([gj_idx_a, gj_idx_b])
+        # gj_idx = np.concatenate([gj_idx_a, gj_idx_b])
         gj_gid_src = np.concatenate([gj_gid_src_a, gj_gid_src_b])
         gj_gid_dest = np.concatenate([gjg_id_dest_a, gj_gid_dest_b])
         neuron_id = np.concatenate([neuron_id_a, neuron_id_b])
-        seg_id = np.concatenate([seg_id_a, seg_id_b])
+        # seg_id = np.concatenate([seg_id_a, seg_id_b])
         compartment = np.concatenate([compartment_a, compartment_b])
         seg_x = np.concatenate([seg_xa, seg_xb])
         cond = np.concatenate([cond_a, cond_b])
@@ -811,8 +772,7 @@ def find_local_gap_junctions(self):
 
     ############################################################################
 
-    # We can only do half the setup of the gap junction if it is split between
-    # two workers.
+    # We can only do half the setup of the gap junction if it is split between two workers.
 
     def connect_network_gap_junctions_local(self):
 
@@ -854,7 +814,9 @@ def add_synapse(self, cell_id_source, cell_id_dest, dend_compartment, section_id
 
         Args:
             cell_id_source: Neuron ID of presynaptic neuron
+            cell_id_dest
             dend_compartment: Dendrite compartment connecting to
+            section_id
             section_dist: Section X
             conductance: Conductance of synapse
             parameter_id: Synapse parameter ID
@@ -863,8 +825,7 @@ def add_synapse(self, cell_id_source, cell_id_dest, dend_compartment, section_id
 
         """
 
-        # You can not locate a point process at
-        # position 0 or 1 if it needs an ion
+        # You can not locate a point process at endpoints (position 0.0 or 1.0) if it needs an ion
         if section_dist == 0.0:
             section_dist = 0.01
         if section_dist == 1.0:
@@ -875,7 +836,7 @@ def add_synapse(self, cell_id_source, cell_id_dest, dend_compartment, section_id
         syn = self.get_synapse(channel_module, dend_compartment, section_dist)
 
         if par_data is not None:
-            # Picking one of the parameter sets stored in parData
+            # Picking one of the parameter sets stored in par_data
             par_id = parameter_id % len(par_data)
 
             par_set = par_data[par_id]
@@ -946,8 +907,7 @@ def add_synapse(self, cell_id_source, cell_id_dest, dend_compartment, section_id
     def add_gap_junction(self,
                          section, section_dist,
                          gid_source_gj, gid_dest_gj,
-                         g_gap_junction=0.5e-9,
-                         gid=None):  # GID unused??
+                         g_gap_junction=0.5e-9):
 
         """
         Add gap junction.
@@ -969,11 +929,9 @@ def add_gap_junction(self,
         # Update thanks to Lizhixin
 
         self.pc.target_var(gj, gj._ref_vgap, gid_dest_gj)
-
         self.pc.source_var(section(section_dist)._ref_v, gid_source_gj, sec=section)
 
         gj.g = g_gap_junction
-        # print("Setting conductance: " + str(GJ.g))
 
     ############################################################################
 
@@ -1017,13 +975,9 @@ def add_external_input(self, input_file=None):
                 continue
 
             for input_type in self.input_data["input"][str(neuron_id)]:
-                neuron_input = self.input_data["input"][str(neuron_id)][input_type]
-
-                loc_type = 1 * np.ones((neuron_input["sectionID"].shape[0],))  # Axon-Dend
 
+                neuron_input = self.input_data["input"][str(neuron_id)][input_type]
                 sections = self.neurons[neuron_id].map_id_to_compartment(neuron_input["sectionID"])
-
-                # Setting individual parameters for synapses
                 mod_file = SnuddaLoad.to_str(neuron_input["modFile"][()])
                 param_list = json.loads(neuron_input["parameterList"][()], object_pairs_hook=OrderedDict)
 
@@ -1044,8 +998,7 @@ def add_external_input(self, input_file=None):
 
                     # Creating NEURON VecStim and vector
                     # https://www.neuron.yale.edu/phpBB/viewtopic.php?t=3125
-                    # import pdb
-                    # pdb.set_trace()
+
                     try:
                         vs = h.VecStim()
                         v = h.Vector(spikes.size)
@@ -1056,10 +1009,9 @@ def add_external_input(self, input_file=None):
                         tstr = traceback.format_exc()
                         print(tstr)
 
-                        assert False, "!!! If you see this, make sure that vecevent.mod is included in nrnivmodl compilation"
+                        assert False, "!!! Make sure that vecevent.mod is included in nrnivmodl compilation"
 
-                    # NEURON: You can not locate a point process at position 0 or 1
-                    # if it needs an ion
+                    # NEURON: You can not locate a point process at position 0 or 1 if it needs an ion
                     if section_x == 0.0:
                         section_x = 0.01
                     elif section_x == 1.0:
@@ -1072,8 +1024,7 @@ def add_external_input(self, input_file=None):
                     nc.weight[0] = neuron_input["conductance"][()] * 1e6  # Neurons needs microsiemens
                     nc.threshold = 0.1
 
-                    # Get the modifications of synapse parameters, specific to
-                    # this synapse
+                    # Get the modifications of synapse parameters, specific to this synapse
                     if param_list is not None and len(param_list) > 0:
                         syn_params = param_list[param_id % len(param_list)]["synapse"]
 
@@ -1180,7 +1131,7 @@ def centre_neurons(self, side_len=None, neuron_id=None):
         centre_pos = np.min(positions, axis=0)
 
         for nid in neuron_id:
-            # pos = self.network_info["neurons"][nid]["position"]
+
             pos = positions[nid, :]
 
             if (abs(pos[0] - centre_pos[0]) <= side_len
@@ -1188,7 +1139,7 @@ def centre_neurons(self, side_len=None, neuron_id=None):
                     and abs(pos[2] - centre_pos[2]) <= side_len):
                 c_id.append(nid)
 
-        print("Centering: Keeping " + str(len(c_id)) + "/" + str(len(neuron_id)))
+        print(f"Centering: Keeping {len(c_id)}/{len(neuron_id)}")
 
         return c_id
 
@@ -1198,8 +1149,7 @@ def add_recording_of_type(self, neuron_type, num_neurons=None):
 
         """ Adds somatic voltage recording to num_neurons of neuron_type. """
 
-        cell_id = self.snudda_loader.get_neuron_id_of_type(neuron_type=neuron_type,
-                                                           num_neurons=num_neurons)
+        cell_id = self.snudda_loader.get_neuron_id_of_type(neuron_type=neuron_type, num_neurons=num_neurons)
 
         self.add_volt_recording_all(cell_id)
 
@@ -1282,7 +1232,7 @@ def add_volt_recording_all(self, cell_id=None):
 
             for sid, sec in enumerate(self.neurons[cid].icell.dend):
                 for seg in sec.allseg():
-                    sec_id.append(sid+1)  # NEURON indexes from 0, Snudda has soma as 0, and first dendrite is 1
+                    sec_id.append(sid + 1)  # NEURON indexes from 0, Snudda has soma as 0, and first dendrite is 1
                     sec_x.append(seg.x)
 
             self.add_volt_recording(cell_id=cid, sec_id=sec_id, sec_x=sec_x)
@@ -1333,7 +1283,6 @@ def add_synapse_current_recording(self, source_id, dest_id):
         synapse_info_list = self.synapse_dict[source_id, dest_id]
 
         for syn, nc, synapse_type_id, sec_id in synapse_info_list:
-
             data = self.sim.neuron.h.Vector()
             data.record(syn._ref_i)
             seg = syn.get_segment()
@@ -1345,62 +1294,6 @@ def add_synapse_current_recording(self, source_id, dest_id):
                                               sec_x=seg.x,
                                               cond=nc.weight[0])
 
-    def add_recording_OLD2(self, cell_id=None, side_len=None):
-
-        """
-        Adds somatic voltage recording to neuron cell_id.
-        """
-
-        self.write_log("Adding somatic recordings")
-
-        if cell_id is None:
-            cell_id = self.neuron_id
-
-        # Does nothing if sideLen is not specified (otherwise, give neurons in
-        # the centre)
-        cell_id = self.centre_neurons(side_len=side_len, neuron_id=cell_id)
-
-        # Only include neuron IDs on this worker, ie those in self.neuronID
-        # (filtering in the if statement)
-        try:
-            cells = dict((k, self.neurons[k])
-                         for k in cell_id if (not self.is_virtual_neuron[k]
-                                              and k in self.neuron_id))
-        except:
-            import traceback
-            t_str = traceback.format_exc()
-            self.write_log(t_str, is_error=True)
-            self.write_log(f"cell_id = {cell_id}")
-            self.write_log(f"is_virtual_neuron = {self.is_virtual_neuron}")
-            self.write_log(f"neuron_id = {self.neuron_id}")
-            self.write_log(f"neurons = {self.neurons}")
-            self.write_log(f"pc_id() = {self.pc.id()}")
-            self.write_log(f"num_neurons = {self.num_neurons}")
-            self.write_log("Does this info help?")
-            sys.exit(-1)
-
-        if len(self.t_save) == 0 or self.t_save is None:
-            # TODO: !!! This needs to be registered in save_network_activity
-            self.t_save = self.sim.neuron.h.Vector()
-            self.t_save.record(self.sim.neuron.h._ref_t)
-
-        for cell_key in cells:
-            cell = cells[cell_key]
-
-            try:
-                v = self.sim.neuron.h.Vector()
-
-                self.pc.threshold(cell_key, self.spike_threshold)    # TODO: Set individual spike thresholds based on parameters
-                v.record(getattr(cell.icell.soma[0](0.5), '_ref_v'))
-                # TODO: !!! This needs to be registered in save_network_activity, and ability to save voltage in compartments and currents
-
-                self.v_save.append(v)
-                self.v_key.append(cell_key)
-            except Exception as e:
-                self.write_log(f"Error: {e}", is_error=True)
-                import pdb
-                pdb.set_trace()
-
     ############################################################################
 
     def run(self, t=1000.0, hold_v=None):
@@ -1427,7 +1320,6 @@ def run(self, t=1000.0, hold_v=None):
         # Make sure all processes are synchronised
         self.pc.barrier()
         self.write_log(f"Running simulation for {t / 1000} s", force_print=True)
-        # self.sim.psolve(t)
         self.sim.run(t, dt=0.025)
         self.pc.barrier()
         self.write_log("Simulation done.")
@@ -1435,54 +1327,6 @@ def run(self, t=1000.0, hold_v=None):
         end_time = timeit.default_timer()
         self.write_log(f"Simulation run time: {end_time - start_time:.1f} s", force_print=True)
 
-    ############################################################################
-
-    def plot(self):
-
-        assert False, "plot is deprecated now"
-
-        """ Save a plot of voltage trace. """
-
-        import matplotlib.pyplot as pyplot
-        pyplot.figure()
-        for v in self.v_save:
-            pyplot.plot(self.t_save, v)
-
-        pyplot.xlabel('Time (ms)')
-        pyplot.ylabel('Voltage (mV)')
-        pyplot.show()
-        from os.path import basename
-        name = basename(self.network_info["configFile"])
-        pyplot.savefig(os.path.join("figures", f"Network-voltage-trace{name}.pdf"))
-
-    ############################################################################
-
-    # def getSpikes(self):
-    #  spiketrain.netconvecs_to_listoflists(self.tSpikes,self.idSpikes)
-
-    ############################################################################
-
-    def write_spikes(self, output_file=None):
-
-        """ Write spikes to output_file. """
-
-        if output_file is None:
-            output_file = self.get_spike_file_name()
-
-        self.write_log(f"Writing spike times to {output_file}", force_print=True)
-
-        for i in range(int(self.pc.nhost())):
-            self.pc.barrier()  # sync all processes
-            if i == int(self.pc.id()):
-                if i == 0:
-                    mode = 'w'
-                else:
-                    mode = 'a'
-                with open(output_file, mode) as spikeFile:
-                    for (t, id) in zip(self.t_spikes, self.id_spikes):
-                        spikeFile.write('%.3f\t%d\n' % (t, id))
-            self.pc.barrier()
-
     ############################################################################
     # export_to_core_neuron contributed by Zhixin, email: 2001210624@pku.edu.cn
 
@@ -1508,19 +1352,21 @@ def export_to_core_neuron(self):
 
     ############################################################################
 
-    # secList is a list of sections
-    # secXList is a list of X values 0 to 1.0
-    # destID is the ID of the neuron receiving synapse (one value!)
-    # voxel coords are the voxel that the synapse is in
+    def verify_synapse_placement(self, sec_list, sec_x_list, dest_id, voxel_coords):
 
-    # We want to check that voxel coords transformed to local coordinate system
-    # of neuron matches with where neuron places the synapse
+        """ Verifies synapse placement.
 
-    def verify_synapse_placement(self, sec_list, sec_x_list, dest_id, voxel_coords):
+            We want to check that voxel coords transformed to local coordinate system
+            of neuron matches with where neuron places the synapse
+
+            Args:
 
-        """ Verifies synapse placement. """
+                sec_list (list) : list of sections
+                sec_x_list (list) : list of X values 0 to 1.0
+                dest_id (int) : ID of the neuron receiving synapse (one value!)
+                voxel_coords : voxel that the synapse is in
 
-        # print("Running verify synapse placement")
+        """
 
         simulation_origo = self.network_info["simulationOrigo"]
         voxel_size = self.network_info["voxelSize"]
@@ -1601,51 +1447,29 @@ def verify_synapse_placement(self, sec_list, sec_x_list, dest_id, voxel_coords):
                     all_sec = [x for x in neuron.h.allsec() if "axon" not in str(x)]
                     for x in np.linspace(0, 1, 10):
                         sec_pos = np.array([[h.x3d(x, sec=sec),
-                                            h.y3d(x, sec=sec),
-                                            h.z3d(x, sec=sec)]
-                                           for sec in all_sec])
+                                             h.y3d(x, sec=sec),
+                                             h.z3d(x, sec=sec)]
+                                            for sec in all_sec])
 
                         ax.scatter(sec_pos[:, 0], sec_pos[:, 1], sec_pos[:, 2], color="blue")
 
                 plt.savefig("DEBUG-plot-bad-synapse-placement.pdf", dpi=600)
 
-
                 import pdb
                 pdb.set_trace()
 
-        # voxelCoords *
-
-        # Get local neuron position
-        # self.neurons["position"]
-
-        # for sec,secX
-        # h.x3d(
-
     ############################################################################
 
     def write_output(self):
 
         self.record.write()
 
-    ############################################################################
-
-    # File format for csv voltage file:
-    # -1,t0,t1,t2,t3 ... (time)
-    # cellID,v0,v1,v2,v3, ... (voltage for cell #ID)
-    # repeat
-
-    ############################################################################
-
-    # File format for csv current file:
-    # -1,t0,t1,t2,t3 ... (time)
-    # cellID,i0,i1,i2,i3, ... (current for cell #ID)
-    # repeat
-
     def write_current(self,
                       output_file="save/traces/network-current",
                       down_sampling=20):
 
         print("This function will be deprecated in the future")
+        assert False, "Remove this assert to use the old code. But better yet, update it to use new SnuddaSaveNetworkRecordings."
 
         """ Writes current to output_file, with option to down sample data to save space. """
 
@@ -1697,7 +1521,8 @@ def write_log(self, text, flush=True, is_error=False, force_print=False):
 
     ############################################################################
 
-    def create_dir(self, dir_name):
+    @staticmethod
+    def create_dir(dir_name):
 
         """ Creates dir_name if needed. """
         if not os.path.isdir(dir_name):
@@ -1894,8 +1719,8 @@ def check_memory_status(self, threshold=0.1):
                         help="Duration of simulation in seconds")
     parser.add_argument("--verbose", action="store_true")
 
-    parser.add_argument("--outputFile", help="Output hdf5 file (from simulation)",
-                                 dest="output_file", default=None)
+    parser.add_argument("--outputFile", help="Output hdf5 file (from simulation)", dest="output_file", default=None)
+
     # If called through "nrniv -python Network_simulate.py ..." then argparse
     # gets confused by -python flag, and we need to ignore it
     # parser.add_argument("-python",help=argparse.SUPPRESS,
@@ -1905,7 +1730,6 @@ def check_memory_status(self, threshold=0.1):
     network_data_file = args.networkFile
     input_file = args.inputFile
     log_file = os.path.join(os.path.dirname(args.networkFile), "log", "network-simulation-log.txt")
-
     save_dir = os.path.join(os.path.dirname(args.networkFile), "simulation")
 
     if not os.path.exists(save_dir):
@@ -1926,7 +1750,6 @@ def check_memory_status(self, threshold=0.1):
     start = timeit.default_timer()
 
     disableGJ = args.disableGJ
-    # assert disableGJ, "Please use --disableGJ for now, need to test code"
     if disableGJ:
         print("!!! WE HAVE DISABLED GAP JUNCTIONS !!!")
 
@@ -1960,9 +1783,7 @@ def check_memory_status(self, threshold=0.1):
     sim.check_memory_status()
     print(f"Running simulation for {tSim} ms.")
     sim.run(tSim)  # In milliseconds
-    
 
-    
     print("Simulation done, saving output")
     sim.write_output()
 
diff --git a/snudda/utils/__init__.py b/snudda/utils/__init__.py
index de11df744..f5eba405d 100644
--- a/snudda/utils/__init__.py
+++ b/snudda/utils/__init__.py
@@ -1,8 +1,8 @@
+from snudda.utils.cleanup import cleanup
 from snudda.utils.load import SnuddaLoad
+from snudda.utils.load_network_simulation import SnuddaLoadNetworkSimulation
 from snudda.utils.numpy_encoder import NumpyEncoder
 from snudda.utils.snudda_path import snudda_parse_path
-from snudda.utils.cleanup import cleanup
-from snudda.utils.load_network_simulation import SnuddaLoadNetworkSimulation
 
 # Keep this one out, it imports neuron, which causes problems in some cases during pip install
 # from snudda.utils.save_network_activity import SnuddaSaveNetworkActivity
diff --git a/snudda/utils/ablate_network.py b/snudda/utils/ablate_network.py
index ef1ea9f3a..63fa7e2e7 100755
--- a/snudda/utils/ablate_network.py
+++ b/snudda/utils/ablate_network.py
@@ -1,16 +1,16 @@
 #!/usr/bin/env python3
+import json
 import os.path
+import sys
 from collections import OrderedDict
 
-from snudda.utils.load import SnuddaLoad
 import h5py
 import numpy as np
-import sys
-import json
 
+from snudda.utils.load import SnuddaLoad
 
-class SnuddaAblateNetwork:
 
+class SnuddaAblateNetwork:
     """ Ablate neurons or synapses from a network.
 
         For an example config see Snudda/examples/config/example-ablation-config.json
@@ -116,7 +116,7 @@ def filter_synapses(self, data_type):
 
         n_original_synapses = synapse_data.shape[0]
 
-        for idx, (pre_id, post_id) in enumerate(zip(synapse_data[:,0], synapse_data[:,1])):
+        for idx, (pre_id, post_id) in enumerate(zip(synapse_data[:, 0], synapse_data[:, 1])):
 
             if idx % 10000000 == 0:
                 print(f"{idx}/{n_original_synapses} synapses processed")
@@ -307,7 +307,6 @@ def write_network(self, out_file_name=None):
 
 
 def snudda_ablate_network_cli():
-
     from argparse import ArgumentParser
 
     # TODO: Fix so ablation can be specified using a json file for more complex ablations
@@ -376,8 +375,8 @@ def snudda_ablate_network_cli():
         if args.remove_connection.count(";") > 0:
 
             for c in args.remove_connection.split(";"):
-                
-                assert args.remove_connection.count(",") == 1, "Format is --remove_connection pre_neuron_type,post_neuron_type"
+                assert args.remove_connection.count(",") == 1, \
+                    "Format is --remove_connection pre_neuron_type, post_neuron_type"
 
                 pre_type, post_type = c.split(",")
                 mod_network.remove_connection(pre_neuron_type=pre_type, post_neuron_type=post_type,
@@ -385,7 +384,8 @@ def snudda_ablate_network_cli():
 
 
         else:
-            assert args.remove_connection.count(",") == 1, "Format is --remove_connection pre_neuron_type,post_neuron_type"
+            assert args.remove_connection.count(",") == 1, \
+                "Format is --remove_connection pre_neuron_type,post_neuron_type"
 
             pre_type, post_type = args.remove_connection.split(",")
             mod_network.remove_connection(pre_neuron_type=pre_type, post_neuron_type=post_type,
diff --git a/snudda/utils/benchmark_logging.py b/snudda/utils/benchmark_logging.py
index b1d52f651..eb3755f0f 100644
--- a/snudda/utils/benchmark_logging.py
+++ b/snudda/utils/benchmark_logging.py
@@ -1,11 +1,10 @@
-import os
 import json
+import os
 import timeit
 from collections import OrderedDict
 
 
 class BenchmarkLogging:
-
     """ Saves benchmark logging when running snudda from command line.
 
     Trivial example below:
@@ -62,7 +61,7 @@ def get_number_of_workers(self, running_neuron):
 
         if running_neuron:
             # We are running neuron, different way to detect number of workers
-            from mpi4py import MPI
+            from mpi4py import MPI   # Import mpi before NEURON for parallel
             from neuron import h
             self.pc = h.ParallelContext()
             return self.pc.nhost()
@@ -149,4 +148,3 @@ def write_log(self):
 
         with open(self.log_file, "w") as fw:
             json.dump(data, fw, indent=4)
-
diff --git a/snudda/utils/cleanup.py b/snudda/utils/cleanup.py
index c3542f7a0..6e0504b1d 100644
--- a/snudda/utils/cleanup.py
+++ b/snudda/utils/cleanup.py
@@ -1,5 +1,4 @@
 def cleanup_memory(d_view, variable_list):
-
     """ Clear variables in variable_list on workers specified by d_view.
 
     Args:
@@ -14,7 +13,6 @@ def cleanup_memory(d_view, variable_list):
 
 # Cleans up memory on workers after execution
 def cleanup(rc, state):
-
     """ When place, detect, prune are run one after the other, we do not need to keep them all in memory
     at the same time. As one finishes, we can clear the memory.
 
diff --git a/snudda/utils/conv_hurt.py b/snudda/utils/conv_hurt.py
index 685ba8c74..c60ba7c84 100644
--- a/snudda/utils/conv_hurt.py
+++ b/snudda/utils/conv_hurt.py
@@ -1,12 +1,14 @@
 # Must have a __init__.py file in module directory
 
-import json
-import h5py
 import csv
-from collections import OrderedDict
+import json
 import os
+from collections import OrderedDict
+
+import h5py
 import numpy as np
 
+
 # TODO: This needs to be updated to match the latest SONATA release.
 
 class ConvHurt(object):
@@ -103,9 +105,9 @@ def write_main_config(self,
         # subsequent elements are the inputs (can be more than one)
 
         node_files = [OrderedDict([("nodes_file", sim_node),
-                                  ("node_types_file", sim_node_type)])]
+                                   ("node_types_file", sim_node_type)])]
         node_files += [OrderedDict([("nodes_file", os.path.join("$NETWORK_DIR", x, f"{x}_nodes.hdf5")),
-                                   ("node_types_file", os.path.join("$NETWORK_DIR", x, f"{x}_node_types.csv"))])
+                                    ("node_types_file", os.path.join("$NETWORK_DIR", x, f"{x}_node_types.csv"))])
                        for x in input_structures]
 
         edge_files = [OrderedDict([("edges_file", sim_edge), ("edge_types_file", sim_edge_type)])]
@@ -460,7 +462,7 @@ def write_input_neurodamus(self, spike_file_name, spikes):
     edge_data = OrderedDict([("sec_id", np.array([10, 22, 33, 24, 15])),
                              ("sec_x", np.array([0.1, 0.3, 0.5, 0.2, 0])),
                              ("syn_weight", np.array([0.1e-9, 2e-9, 3e-9,
-                                                     0.3e-9, 0.1e-9])),
+                                                      0.3e-9, 0.1e-9])),
                              ("delay", 1e3 * np.array([1e-3, 4e-3, 2e-3, 5e-3, 1e-3]))])
 
     ch.write_edges(edge_file="striatum_edges.hdf5",
diff --git a/snudda/utils/create_parameter_morphology_input_map.py b/snudda/utils/create_parameter_morphology_input_map.py
index daa0556c3..ab7597899 100644
--- a/snudda/utils/create_parameter_morphology_input_map.py
+++ b/snudda/utils/create_parameter_morphology_input_map.py
@@ -1,6 +1,5 @@
-import os
-from glob import glob
 import json
+import os
 from collections import OrderedDict
 
 
@@ -8,7 +7,6 @@ class CreateParameterMorphologyInputMap:
 
     def __init__(self):
 
-
         pass
 
     # TODO: Parse through all the neuron types, and neuron directories
@@ -33,7 +31,6 @@ def parse_neuron(self, neuron_path):
                 mapping_data[key] = OrderedDict()
 
             for m in p["morphology"]:
-
                 mapping_data[key][m] = OrderedDict()
                 mapping_data[key][m]["Cortical"] = 100
                 mapping_data[key][m]["Thalamic"] = 100
diff --git a/snudda/utils/cut.py b/snudda/utils/cut.py
index 2494f5ab1..bf1b04845 100755
--- a/snudda/utils/cut.py
+++ b/snudda/utils/cut.py
@@ -14,15 +14,14 @@
 import sys
 
 import h5py
-import numpy as np
-import time
 import numexpr
+import numpy as np
+
 
 # TODO: Check that no population unit list needs to be remapped also, this is old code that was just refactored...
 
 
 class SnuddaCut(object):
-
     """ Cuts part of the volume, to simulate creating a slice of tissue, or other cut. """
 
     def __init__(self, network_file, cut_equation="z>0",
@@ -95,7 +94,7 @@ def write_cut_slice(self, cut_equation_lambda):
             print("No somas left, aborting!")
             sys.exit(-1)
 
-        print(f"Keeping {num_soma_keep} out of {len(soma_keep_flag)}" 
+        print(f"Keeping {num_soma_keep} out of {len(soma_keep_flag)}"
               "neurons (the others have soma outside of cut plane)")
 
         # We need to remap neuronID in the synapses and gap junction matrix
@@ -228,7 +227,6 @@ def soma_inside(self, cut_equation_lambda):
 
     def synapses_inside(self, cut_equation_lambda, data_type="synapses"):
 
-
         """ Check if synapses are inside cut_equation_lambda. Returns a numpy bool array.
 
         Args:
diff --git a/snudda/utils/export_connection_matrix.py b/snudda/utils/export_connection_matrix.py
index 88ee4210a..c958d4e42 100755
--- a/snudda/utils/export_connection_matrix.py
+++ b/snudda/utils/export_connection_matrix.py
@@ -1,10 +1,11 @@
 #!/usr/bin/env python3
 
 import numpy as np
+
 from snudda.utils.load import SnuddaLoad
 
-class SnuddaExportConnectionMatrix(object):
 
+class SnuddaExportConnectionMatrix(object):
     """ Exports a connection matrix from network. """
 
     def __init__(self, in_file, out_file, save_sparse=True, save_on_init=True):
diff --git a/snudda/utils/export_eroded_connection_matrix.py b/snudda/utils/export_eroded_connection_matrix.py
index caeece9a3..0cf9ced48 100755
--- a/snudda/utils/export_eroded_connection_matrix.py
+++ b/snudda/utils/export_eroded_connection_matrix.py
@@ -8,7 +8,6 @@
 class SnuddaExportErodedConnectionMatrix(SnuddaExportConnectionMatrix):
 
     def __init__(self, in_file, out_file, fraction_kept=1.0, save_sparse=True, permute=False):
-
         super().__init__(in_file=in_file, out_file=out_file, save_sparse=save_sparse, save_on_init=False)
 
         self.con_mat = self.erode(mat=self.con_mat, fraction_kept=fraction_kept)
@@ -20,7 +19,6 @@ def __init__(self, in_file, out_file, fraction_kept=1.0, save_sparse=True, permu
 
     @staticmethod
     def erode(mat, fraction_kept=1.0):
-
         erode_mat = np.random.uniform(size=mat.shape) <= fraction_kept
         mat = np.multiply(erode_mat, mat)
 
@@ -28,7 +26,6 @@ def erode(mat, fraction_kept=1.0):
 
     @staticmethod
     def permute_all(mat):
-
         row_permute = np.random.permutation(mat.shape[0])
         col_permute = np.random.permutation(mat.shape[1])
 
diff --git a/snudda/utils/export_sonata.py b/snudda/utils/export_sonata.py
index f56ef425b..7d4508fa3 100644
--- a/snudda/utils/export_sonata.py
+++ b/snudda/utils/export_sonata.py
@@ -5,12 +5,13 @@
 # - Check what axon and dendrite propagation speeds should be
 #
 
-import sys
 import json
+import os
+import sys
 from collections import OrderedDict
-import numpy as np
+
 import h5py
-import os
+import numpy as np
 
 from conv_hurt import ConvHurt
 from load import SnuddaLoad
@@ -131,30 +132,30 @@ def __init__(self, network_file, input_file, out_dir):
 
         # These should match edgeTypeLookup
         edge_csv_data = OrderedDict([('template',
-                                     ['MSGABA',  # 1
-                                      'MSGABA',  # 2
-                                      'MSGABA',  # 3
-                                      'MSGABA',  # 4
-                                      'FSGABA',  # 5
-                                      'FSGABA',  # 6
-                                      'AChSyn',  # 7
-                                      'AChSyn',  # 8
-                                      'FSGABA',  # 9
-                                      'MSGABA',  # 10
-                                      'MSGABA',  # 11
-                                      'MSGABA',  # 12
-                                      'MSGABA',  # 13
-                                      'FSGABA',  # 14
-                                      'AChSyn',  # 15
-                                      'ThalamusGlu',  # 16
-                                      'ThalamusGlu',  # 17
-                                      'ThalamusGlu',  # 18
-                                      'ThalamusGlu',  # 19
-                                      'CortexGlu',  # 20
-                                      'CortexGlu',  # 21
-                                      'CortexGlu',  # 22
-                                      'CortexGlu',  # 23
-                                      ])])
+                                      ['MSGABA',  # 1
+                                       'MSGABA',  # 2
+                                       'MSGABA',  # 3
+                                       'MSGABA',  # 4
+                                       'FSGABA',  # 5
+                                       'FSGABA',  # 6
+                                       'AChSyn',  # 7
+                                       'AChSyn',  # 8
+                                       'FSGABA',  # 9
+                                       'MSGABA',  # 10
+                                       'MSGABA',  # 11
+                                       'MSGABA',  # 12
+                                       'MSGABA',  # 13
+                                       'FSGABA',  # 14
+                                       'AChSyn',  # 15
+                                       'ThalamusGlu',  # 16
+                                       'ThalamusGlu',  # 17
+                                       'ThalamusGlu',  # 18
+                                       'ThalamusGlu',  # 19
+                                       'CortexGlu',  # 20
+                                       'CortexGlu',  # 21
+                                       'CortexGlu',  # 22
+                                       'CortexGlu',  # 23
+                                       ])])
 
         ch.write_edges_csv(edge_csv_file="Striatum/Striatum_edge_types.csv",
                            edge_type_id=edge_type_id,
diff --git a/snudda/utils/fake_load.py b/snudda/utils/fake_load.py
index 893c5d984..c66073b99 100644
--- a/snudda/utils/fake_load.py
+++ b/snudda/utils/fake_load.py
@@ -1,8 +1,10 @@
 import json
+from collections import OrderedDict
+
 import numpy as np
+
 from snudda.utils.load import SnuddaLoad
 from snudda.utils.numpy_encoder import NumpyEncoder
-from collections import OrderedDict
 
 
 class FakeLoad(SnuddaLoad):
@@ -22,8 +24,8 @@ def export_json(self, json_file_name):
             # Fix for connectivityDistributions
             data_copy["connectivityDistributions"] = OrderedDict()
             for pre_id, post_id in self.data["connectivityDistributions"].keys():
-                data_copy["connectivityDistributions"][f"{pre_id}$${post_id}"] =\
-                    self.data["connectivityDistributions"][pre_id,post_id]
+                data_copy["connectivityDistributions"][f"{pre_id}$${post_id}"] = \
+                    self.data["connectivityDistributions"][pre_id, post_id]
 
             data_copy["connectivityDistributions"]
 
@@ -56,4 +58,3 @@ def import_json(self, json_file_name):
 
         if "config" in self.data:
             self.config = json.loads(self.data["config"], object_pairs_hook=OrderedDict)
-
diff --git a/snudda/utils/input_helper.py b/snudda/utils/input_helper.py
index 28bd8002f..0b11bbef2 100644
--- a/snudda/utils/input_helper.py
+++ b/snudda/utils/input_helper.py
@@ -2,4 +2,4 @@ def to_list(val):
     if type(val) != list:
         val = [val]
 
-    return val
\ No newline at end of file
+    return val
diff --git a/snudda/utils/load.py b/snudda/utils/load.py
index 8d9e30e6a..586a91fc5 100755
--- a/snudda/utils/load.py
+++ b/snudda/utils/load.py
@@ -1,16 +1,15 @@
 #!/usr/bin/env python3
+import json
+import sys
+import timeit
 from collections import OrderedDict
 
 import numpy as np
-import timeit
-import json
-import sys
 
 from snudda.neurons.neuron_prototype import NeuronPrototype
 
 
 class SnuddaLoad(object):
-
     """
     Load data from network-neuron-positions.hdf5 or network-neuron-synapses.hdf5 into python dictionary
     """
@@ -88,6 +87,7 @@ def load_hdf5(self, network_file, load_synapses=True, load_morph=False):
         Args:
             network_file (str) : Network file to load data from
             load_synapses (bool) : Load synapses into memory, or read on demand from file (keeps file open)
+            load_morph
 
         Returns:
             data (dictionary) : Dictionary with data.
@@ -176,19 +176,29 @@ def load_hdf5(self, network_file, load_synapses=True, load_morph=False):
             data["nNeurons"] = f["network/neurons/neuronID"].shape[0]
             data["neuronID"] = f["network/neurons/neuronID"][()]
 
-            try:
-                data["nSynapses"] = f["network/nSynapses"][0]
+            if "nSynapses" in f["network"]:
+                if f["network/nSynapses"].shape == ():
+                    data["nSynapses"] = f["network/nSynapses"][()]
+                else:
+                    data["nSynapses"] = f["network/nSynapses"][0]
+
                 if data["nSynapses"] != f["network/synapses"].shape[0]:
                     print(f"Expected {data['nSynapses']} synapses, found {f['network/synapses'].shape[0]} synapse rows")
-            except:
+                    data["nSynapses"] = f["network/synapses"].shape[0]
+            else:
                 data["nSynapses"] = f["network/synapses"].shape[0]
 
-            try:
-                data["nGapJunctions"] = f["network/nGapJunctions"][0]
+            if "nGapJunctions" in f["network"]:
+                if f["network/nGapJunctions"].shape == ():
+                    data["nGapJunctions"] = f["network/nGapJunctions"][()]
+                else:
+                    data["nGapJunctions"] = f["network/nGapJunctions"][0]
+
                 if data["nGapJunctions"] != f["network/gapJunctions"].shape[0]:
                     print(f"Expected {data['nGapJunctions']} gap junctions, "
                           f"found {f['network/gapJunctions'].shape[0]} gap junction rows")
-            except:
+                    data["nGapJunctions"] = f["network/gapJunctions"].shape[0]
+            else:
                 data["nGapJunctions"] = f["network/gapJunctions"].shape[0]
 
             if data["nSynapses"] > 100e6:
@@ -218,7 +228,7 @@ def load_hdf5(self, network_file, load_synapses=True, load_morph=False):
                 # !!! Convert from voxel idx to coordinates
                 if f["network/synapses"].shape[0] > 0:
                     data["synapseCoords"] = f["network/synapses"][:, 2:5] * f["meta/voxelSize"][()] \
-                        + f["meta/simulationOrigo"][()]
+                                            + f["meta/simulationOrigo"][()]
                 else:
                     data["synapseCoords"] = np.zeros((3, 0))
             else:
@@ -339,7 +349,7 @@ def extract_neurons(hdf5_file):
             axon_density_type, axon_density, axon_density_radius, \
             axon_density_bounds_xyz, \
             morph, neuron_path, \
-            parameter_id, morphology_id, modulation_id,\
+            parameter_id, morphology_id, modulation_id, \
             parameter_key, morphology_key, modulation_key \
                 in zip(hdf5_file["network/neurons/name"][:],
                        hdf5_file["network/neurons/neuronID"][:],
@@ -785,7 +795,6 @@ def get_population_unit_members(self, population_unit, num_neurons=None, random_
 
 
 def snudda_load_cli():
-
     """ Command line parser for SnuddaLoad script """
 
     from argparse import ArgumentParser
@@ -840,7 +849,7 @@ def snudda_load_cli():
         else:
             print(f"Neurons of type {args.listT}:")
             n_of_type = [(x["neuronID"], x["name"]) for x in nl.data["neurons"]
-                       if x["type"] == args.listT]
+                         if x["type"] == args.listT]
             for nid, name in n_of_type:
                 print("%d : %s" % (nid, name))
 
@@ -862,7 +871,7 @@ def snudda_load_cli():
             if args.detailed:
                 idx = np.where(synapses[0][:, 0] == nid)
                 for i in idx[0]:
-                    print(f" -- SegID {synapses[0][i, 9]}, SegX {synapses[0][i, 10]*1e-3:.4f}, "
+                    print(f" -- SegID {synapses[0][i, 9]}, SegX {synapses[0][i, 10] * 1e-3:.4f}, "
                           f"Coord: {synapses[1][i, :]}")
 
                 print("")
@@ -880,7 +889,7 @@ def snudda_load_cli():
             if args.detailed:
                 idx = np.where(synapses[0][:, 1] == nid)
                 for i in idx[0]:
-                    print(f" -- SegID {synapses[0][i, 9]}, SegX {synapses[0][i, 10]*1e-3:.4f}, "
+                    print(f" -- SegID {synapses[0][i, 9]}, SegX {synapses[0][i, 10] * 1e-3:.4f}, "
                           f"Coord: {synapses[1][i, :]}")
 
                 print("")
diff --git a/snudda/utils/load_network_simulation.py b/snudda/utils/load_network_simulation.py
index 05e07bed9..ff53b7586 100755
--- a/snudda/utils/load_network_simulation.py
+++ b/snudda/utils/load_network_simulation.py
@@ -1,8 +1,8 @@
 #!/usr/bin/env python3
 import os
 
-import numpy as np
 import h5py
+import numpy as np
 
 from snudda.utils.load import SnuddaLoad
 
@@ -57,15 +57,16 @@ def merge_spikes(self, spike_data=None):
 
         n_spikes = 0
         for spikes in spike_data.values():
-            n_spikes += len(spikes)
+            n_spikes += spikes.size
 
         merged_spike_data = np.full((n_spikes, 2), np.nan)
         idx = 0
 
         for neuron_id, spikes in spike_data.items():
-            merged_spike_data[idx:idx+len(spikes), 0] = spikes
-            merged_spike_data[idx:idx+len(spikes), 1] = neuron_id
-            idx += len(spikes)
+            if spikes.size > 0:
+                merged_spike_data[idx:idx + spikes.size, 0] = spikes
+                merged_spike_data[idx:idx + spikes.size, 1] = neuron_id
+                idx += spikes.size
 
         # Sort the spikes after time
         idx = np.argsort(merged_spike_data[:, 0])
@@ -96,7 +97,7 @@ def get_spikes(self, neuron_id=None):
 
         elif np.issubdtype(type(neuron_id), np.integer):
             if str(neuron_id) in self.network_simulation_file["neurons"] \
-               and "spikes" in self.network_simulation_file[f"neurons/{neuron_id}"]:
+                    and "spikes" in self.network_simulation_file[f"neurons/{neuron_id}"]:
                 spike_data = self.network_simulation_file[f"neurons/{neuron_id}/spikes/data"][()].copy()
             else:
                 spike_data = np.array([])
@@ -105,7 +106,7 @@ def get_spikes(self, neuron_id=None):
             spike_data = dict()
             for nid in neuron_id:
                 if str(nid) in self.network_simulation_file["neurons"] \
-                   and "spikes" in self.network_simulation_file[f"neurons/{nid}"]:
+                        and "spikes" in self.network_simulation_file[f"neurons/{nid}"]:
                     spike_data[nid] = self.network_simulation_file[f"neurons/{neuron_id}/spikes/data"][()].copy()
                 else:
                     spike_data[nid] = np.array([])
@@ -135,7 +136,8 @@ def get_data(self, data_type, neuron_id=None):
 
                 if "synapse_type" in self.network_simulation_file["neurons"][snid][data_type]:
                     synapse_type = self.network_simulation_file["neurons"][snid][data_type]["synapse_type"][()].copy()
-                    presynaptic_id = self.network_simulation_file["neurons"][snid][data_type]["presynaptic_id"][()].copy()
+                    presynaptic_id = self.network_simulation_file["neurons"][snid][data_type]["presynaptic_id"][
+                        ()].copy()
                     cond = self.network_simulation_file["neurons"][snid][data_type]["cond"][()].copy()
                     syn_info[inid] = (synapse_type, presynaptic_id, cond)
 
@@ -178,7 +180,8 @@ def get_synaptic_current(self, pre_id=None, post_id=None):
             if len(idx) > 0:
                 filtered_current[neuron_id] = current[neuron_id][:, idx]
                 filtered_sec_id_x[neuron_id] = (sec_id_x[neuron_id][0][idx], sec_id_x[neuron_id][1][idx])
-                filtered_syn_info[neuron_id] = (syn_info[neuron_id][0][idx], syn_info[neuron_id][1][idx], syn_info[neuron_id][2][idx])
+                filtered_syn_info[neuron_id] = (syn_info[neuron_id][0][idx], syn_info[neuron_id][1][idx],
+                                                syn_info[neuron_id][2][idx])
 
         return filtered_current, filtered_sec_id_x, filtered_syn_info
 
@@ -236,5 +239,4 @@ def load_network_simulation_cli():
 
 
 if __name__ == "__main__":
-
-    load_network_simulation_cli()
\ No newline at end of file
+    load_network_simulation_cli()
diff --git a/snudda/utils/load_spike_data.py b/snudda/utils/load_spike_data.py
index b259cc6bd..d3bc4526e 100755
--- a/snudda/utils/load_spike_data.py
+++ b/snudda/utils/load_spike_data.py
@@ -1,6 +1,7 @@
 #!/usr/bin/env python3
 
 import numpy as np
+
 from snudda.utils.load import SnuddaLoad
 
 
@@ -72,11 +73,11 @@ def get_spikes_from(self,
         return spikes, neuron_id
 
     def print_freq_info(self,
-                      neuron_id=None,
-                      neuron_name=None,
-                      neuron_type=None,
-                      time_range=None
-                      ):
+                        neuron_id=None,
+                        neuron_name=None,
+                        neuron_type=None,
+                        time_range=None
+                        ):
 
         freq_list, nid = self.get_freq(neuron_id=neuron_id,
                                        neuron_name=neuron_name,
@@ -118,7 +119,6 @@ def get_spikes(self, neuron_id, time_range=None):
 
 
 def snudda_load_spike_data_cli():
-
     """ Command line parser for SnuddaLoadSpikeData script """
 
     from argparse import ArgumentParser
@@ -149,5 +149,4 @@ def snudda_load_spike_data_cli():
 
 
 if __name__ == "__main__":
-
-    snudda_load_spike_data_cli()
\ No newline at end of file
+    snudda_load_spike_data_cli()
diff --git a/snudda/utils/memory.py b/snudda/utils/memory.py
index 610b4d4fd..6c81ae220 100644
--- a/snudda/utils/memory.py
+++ b/snudda/utils/memory.py
@@ -4,7 +4,6 @@
 
 
 def memory_status():
-
     """ Returns memory status. Tuple (memory available, memory total) """
 
     mem = virtual_memory()
diff --git a/snudda/utils/numpy_encoder.py b/snudda/utils/numpy_encoder.py
index d1c921923..8538b996f 100644
--- a/snudda/utils/numpy_encoder.py
+++ b/snudda/utils/numpy_encoder.py
@@ -1,4 +1,5 @@
 import json
+
 import numpy as np
 
 
@@ -17,4 +18,3 @@ def default(self, obj):
         else:
             # return super(NumpyEncoder, self).default(obj)
             return json.JSONEncoder.default(self, obj)
-
diff --git a/snudda/utils/pip_upgrade.py b/snudda/utils/pip_upgrade.py
index 6fc0b2680..748a2b3ff 100644
--- a/snudda/utils/pip_upgrade.py
+++ b/snudda/utils/pip_upgrade.py
@@ -1,5 +1,6 @@
-import pkg_resources
 from subprocess import call
 
+import pkg_resources
+
 packages = [dist.project_name for dist in pkg_resources.working_set]
 call("pip3 install --upgrade " + ' '.join(packages), shell=True)
diff --git a/snudda/utils/reposition_neurons.py b/snudda/utils/reposition_neurons.py
index 11180cbe0..8f52b965c 100644
--- a/snudda/utils/reposition_neurons.py
+++ b/snudda/utils/reposition_neurons.py
@@ -2,7 +2,6 @@
 
 
 class RepositionNeurons(object):
-
     """ Reposition neurons in the network file. """
 
     def __init__(self, position_file):
@@ -40,7 +39,7 @@ def place(self, neuron_id, position, rotation=None, verbose=True):
             verbose : Print info?
         """
 
-        info = (f"Moving neuron {neuron_id} from {self.hdf5_file['network/neurons/position'][neuron_id]} " 
+        info = (f"Moving neuron {neuron_id} from {self.hdf5_file['network/neurons/position'][neuron_id]} "
                 f"to {position}")
         if rotation is not None:
             info += f" setting rotation to {rotation}"
@@ -51,7 +50,7 @@ def place(self, neuron_id, position, rotation=None, verbose=True):
         self.hdf5_file["network/neurons/position"][neuron_id] = position
 
         if rotation is not None:
-            self.hdf5_file["network/neurons/rotation"][neuron_id] = rotation.reshape((9, ))
+            self.hdf5_file["network/neurons/rotation"][neuron_id] = rotation.reshape((9,))
 
     def set_morphology_id(self, neuron_id, morphology_id):
 
diff --git a/snudda/utils/save_network_recording.py b/snudda/utils/save_network_recording.py
index d35209b9e..7ae3902ac 100644
--- a/snudda/utils/save_network_recording.py
+++ b/snudda/utils/save_network_recording.py
@@ -5,6 +5,7 @@
 from mpi4py import MPI  # This must be imported before neuron, to run parallel
 from neuron import h  # , gui
 
+
 # TODO:
 
 # Check if we can get synapse row number stored somehow...
@@ -29,6 +30,7 @@ class NeuronRecordings:
     """
         Container class for all recordings associated with a neuron.
     """
+
     def __init__(self, neuron_id):
         """
         Constructor
@@ -70,7 +72,6 @@ def register_synapse_data(self, data, data_type, synapse_type, presynaptic_id, s
 class SynapseData:
 
     def __init__(self, neuron_id, data_type):
-
         self.neuron_id = neuron_id
         self.data = []
         self.data_type = data_type
@@ -116,7 +117,6 @@ def __init__(self, neuron_id, data_type):
         self.sec_x = []
 
     def append(self, data, sec_id, sec_x):
-
         # !!! Issue (?): The same compartment can hold several recordings now.
 
         """
@@ -129,7 +129,7 @@ def append(self, data, sec_id, sec_x):
 
         """
         self.data.append(data)
-        
+
         self.sec_id.append(sec_id)
         self.sec_x.append(sec_x)
 
@@ -210,7 +210,7 @@ def spike_sort(t_spikes, id_spikes):
         for idx in spikes:
             assert len(spikes[idx]) == 0 or not np.isnan(spikes[idx][-1])
             assert (idx in spike_ctr and spikes[idx].shape[0] == spike_ctr[idx]) \
-                or (idx not in spike_ctr and len(spikes[idx]) == 0)
+                   or (idx not in spike_ctr and len(spikes[idx]) == 0)
 
         return spikes
 
@@ -296,7 +296,8 @@ def write(self):
 
                         if isinstance(m, SynapseData):
                             data_group.create_dataset("synapse_type", data=np.array(m.synapse_type), compression="gzip")
-                            data_group.create_dataset("presynaptic_id", data=np.array(m.presynaptic_id), compression="gzip")
+                            data_group.create_dataset("presynaptic_id", data=np.array(m.presynaptic_id),
+                                                      compression="gzip")
                             data_group.create_dataset("cond", data=np.array(m.cond), compression="gzip")
 
                 out_file.close()
@@ -330,7 +331,7 @@ def write_OLD(self, t_save, v_save, v_key, t_spikes, id_spikes, output_file=None
                         out_file["voltData"].create_dataset("time", data=t_save * 1e-3, compression="gzip")
 
                     for neuron_id, voltage in zip(v_key, v_save):
-                        out_file["voltData"].create_dataset(str(neuron_id), data=voltage*1e-3, compression="gzip")
+                        out_file["voltData"].create_dataset(str(neuron_id), data=voltage * 1e-3, compression="gzip")
 
                     out_file.close()
 
diff --git a/snudda/utils/snudda_path.py b/snudda/utils/snudda_path.py
index e1c4d5424..b808a626f 100644
--- a/snudda/utils/snudda_path.py
+++ b/snudda/utils/snudda_path.py
@@ -1,21 +1,24 @@
 import os
 
+
 # We allow user to use $DATA to specify the Snudda data folder.
 # Default is the Snudda/snudda/data folder, but the user can set the SNUDDA_DATA environment variable
 #
 
 
-def snudda_parse_path(path):
-
+def snudda_parse_path(path, snudda_data=None):
     """ Parses a data path, replacing $DATA with the path to SNUDDA_DATA set by environment variable.
 
     Args:
         path (str) : Path to modify
+        snudda_data (str) : Path to SNUDDA_DATA, this is optional, and if given overrides environment variable
         """
 
     if path and ("$DATA" in path or "$SNUDDA_DATA" in path):
 
-        if "SNUDDA_DATA" in os.environ:
+        if snudda_data:
+            data_path_str = snudda_data
+        elif "SNUDDA_DATA" in os.environ:
             data_path_str = os.environ["SNUDDA_DATA"]
         else:
             data_path_str = os.path.join(os.path.dirname(__file__), os.pardir, "data")
@@ -42,15 +45,22 @@ def snudda_path_exists(path):
     return os.path.exists(snudda_parse_path(path))
 
 
-def snudda_simplify_path(path):
+def snudda_simplify_path(path, snudda_data=None):
     """ Simplifies path, replacing any occurance of SNUDDA_DATA in the path with $SNUDDA_DATA.
 
     Args:
         path (str) : Path to be simplified
+        snudda_data (str) : Path to SNUDDA_DATA, this is optional, and if given overrides environment variable
+
     """
-    data_path = snudda_parse_path("$SNUDDA_DATA")
+
+    if snudda_data:
+        data_path = snudda_data
+    else:
+        data_path = snudda_parse_path("$SNUDDA_DATA")
+
     real_path = os.path.realpath(path)
-    
+
     if path and data_path in real_path:
         path = real_path.replace(data_path, "$SNUDDA_DATA")
 
diff --git a/snudda/utils/swap_to_degenerated_morphologies.py b/snudda/utils/swap_to_degenerated_morphologies.py
new file mode 100644
index 000000000..15936c49a
--- /dev/null
+++ b/snudda/utils/swap_to_degenerated_morphologies.py
@@ -0,0 +1,600 @@
+import json
+import os
+
+import h5py
+import numpy as np
+from scipy.spatial import KDTree
+
+from argparse import ArgumentParser, RawTextHelpFormatter
+
+from snudda.neurons.neuron_prototype import NeuronPrototype
+from snudda.utils.load import SnuddaLoad
+from snudda.utils.snudda_path import snudda_simplify_path, snudda_parse_path
+
+
+class SwapToDegenerateMorphologies:
+
+    def __init__(self, original_network_file, new_network_file,
+                 original_snudda_data_dir, new_snudda_data_dir,
+                 original_input_file, new_input_file):
+
+        """ This code replaces the neuron morphologies in the original network with user provided degenerated copies
+            of the neurons. The synapses that are on removed dendritic or axonal branches will also be removed.
+            The section ID and section X is also updated to match the new degenerated morphologies.
+
+            Args:
+                original_network_file (str) : Path to input network-synapses.hdf5
+                new_network_file (str) : Path to output network-synapses.hdf5
+                original_snudda_data_dir (str) : Path to SNUDDA_DATA for original network
+                new_snudda_data_dir (str) : Path to SNUDDA_DATA for new network
+            """
+
+        self.original_network_file = original_network_file
+        self.new_network_file = new_network_file
+        self.new_hdf5 = None
+
+        self.original_snudda_data_dir = original_snudda_data_dir
+        self.new_snudda_data_dir = new_snudda_data_dir
+
+        assert self.original_snudda_data_dir != self.new_snudda_data_dir, \
+            f"SNUDDA_DATA_DIR should be different for WT and degenerated"
+
+        self.original_input_file = original_input_file
+        self.new_input_file = new_input_file
+
+        self.original_network_loader = SnuddaLoad(self.original_network_file, load_synapses=False)
+        self.old_hdf5 = self.original_network_loader.hdf5_file
+        self.old_data = self.original_network_loader.data
+
+        self.morphology_map = dict()
+        self.section_lookup = dict()
+        self.neuron_cache = dict()
+
+        self.create_section_lookup()
+        self.kd_tree_cache = dict()
+
+    def close(self):
+        self.new_hdf5.close()
+        self.old_hdf5.close()
+
+    def write_new_network_file(self):
+
+        if not os.path.isdir(os.path.dirname(self.new_network_file)):
+            os.mkdir(os.path.dirname(self.new_network_file))
+
+        print(f"Writing new network to {self.new_network_file}")
+        self.new_hdf5 = h5py.File(self.new_network_file, "w")
+        self.old_hdf5.copy(source=self.old_hdf5["meta"], dest=self.new_hdf5)
+        network_group = self.new_hdf5.create_group("network")
+        self.old_hdf5.copy(source=self.old_hdf5["network/neurons"], dest=self.new_hdf5["network"])
+
+        # Update parameter keys and morphology keys
+        for idx, neuron_id in enumerate(self.new_hdf5["network/neurons/neuronID"]):
+            assert idx == neuron_id, "There should be no gaps in numbering."
+            param_key, morph_key, neuron_path, param_id, morph_id = self.find_morpology(neuron_id)
+            self.new_hdf5[f"network/neurons/parameterKey"][idx] = param_key
+            self.new_hdf5[f"network/neurons/morphologyKey"][idx] = morph_key
+            self.new_hdf5[f"network/neurons/neuronPath"][idx] = neuron_path
+            self.new_hdf5[f"network/neurons/parameterID"][idx] = param_id
+            self.new_hdf5[f"network/neurons/morphologyID"][idx] = morph_id
+
+            old_morph = SnuddaLoad.to_str(self.new_hdf5[f"network/neurons/morphology"][idx])
+            new_morph = old_morph.replace(self.original_snudda_data_dir, self.new_snudda_data_dir)
+            self.new_hdf5[f"network/neurons/morphology"][idx] = new_morph
+
+
+        self.filter_synapses()
+        self.filter_gap_junctions()
+
+    def synapse_iterator(self, data_type=None, load_synapses=True):
+
+        """ Each iteration will return the synapses between one pair of neurons. """
+
+        data_loc = "network/synapses"
+        if data_type is not None and data_type == "gapJunctions":
+            data_loc = "network/gapJunctions"
+            num_synapses = self.old_hdf5["network/nGapJunctions"][()]
+        else:
+            num_synapses = self.old_hdf5["network/nSynapses"][()]
+
+        start_idx = 0
+        next_idx = 0
+
+        # Load synapses into memory
+        if load_synapses:
+            synapses = self.old_hdf5[data_loc][()].copy()
+        else:
+            synapses = self.old_hdf5[data_loc]
+
+        assert num_synapses == synapses.shape[0]
+
+        if num_synapses > 0:
+            last_pre = synapses[0, 0]
+            last_post = synapses[0, 1]
+
+        while next_idx < num_synapses:
+            while next_idx < num_synapses \
+                    and synapses[next_idx, 0] == last_pre \
+                    and synapses[next_idx, 1] == last_post:
+                next_idx += 1
+                if next_idx % 10000 == 0:
+                    print(f"{next_idx} / {num_synapses}")
+
+            if next_idx < num_synapses:
+                last_pre = synapses[next_idx, 0]
+                last_post = synapses[next_idx, 1]
+
+            yield synapses[start_idx:next_idx, :]
+            start_idx = next_idx
+
+        print(f"{next_idx} / {num_synapses}")
+
+    def gap_junction_iterator(self, load_gap_junctions=True):
+
+        """ Each iteration will return the gap junctions between one pair of neurons. """
+
+        return self.synapse_iterator(data_type="gapJunctions", load_synapses=load_gap_junctions)
+
+    def filter_synapses(self):
+        # First version, will keep all synapses in memory to write a more efficient file
+        new_synapses = np.zeros(self.old_hdf5["network/synapses"].shape,
+                                dtype=self.old_hdf5["network/synapses"].dtype)
+        syn_ctr = 0
+
+        for synapses in self.synapse_iterator():
+            new_syn = self.filter_synapses_helper(synapses)
+            new_synapses[syn_ctr:syn_ctr + new_syn.shape[0]] = new_syn
+            syn_ctr += new_syn.shape[0]
+
+        self.new_hdf5["network"].create_dataset("synapses", data=new_synapses[:syn_ctr, :], compression="lzf")
+
+        num_synapses = np.zeros((1,), dtype=np.uint64)
+        self.new_hdf5["network"].create_dataset("nSynapses", data=syn_ctr, dtype=np.uint64)
+
+        print(f"Keeping {self.new_hdf5['network/nSynapses'][()]} "
+              f"out of {self.old_hdf5['network/nSynapses'][()]} synapses "
+              f"({self.new_hdf5['network/nSynapses'][()] / self.old_hdf5['network/nSynapses'][()]*100:.3f} %)")
+
+    def filter_gap_junctions(self):
+        # First version, will keep all synapses in memory to write a more efficient file
+        new_gap_junctions = np.zeros(self.old_hdf5["network/gapJunctions"].shape,
+                                     dtype=self.old_hdf5["network/gapJunctions"].dtype)
+        gj_ctr = 0
+
+        for gj in self.gap_junction_iterator():
+            new_gj = self.filter_gap_junctions_helper(gj)
+            new_gap_junctions[gj_ctr:gj_ctr + new_gj.shape[0]] = new_gj
+            gj_ctr += new_gj.shape[0]
+
+        self.new_hdf5["network"].create_dataset("gapJunctions", data=new_gap_junctions[:gj_ctr, :], compression="lzf")
+
+        num_gap_junctions = np.zeros((1,), dtype=np.uint64)
+        self.new_hdf5["network"].create_dataset("nGapJunctions", data=gj_ctr, dtype=np.uint64)
+
+        print(f"Keeping {self.new_hdf5['network/nGapJunctions'][()]} "
+              f"out of {self.old_hdf5['network/nGapJunctions'][()]} gap junctions "
+              f"({self.new_hdf5['network/nGapJunctions'][()] / self.old_hdf5['network/nGapJunctions'][()]*100:.3f} %)")
+
+    def get_morphology(self, neuron_id=None, hdf5=None, neuron_path=None, parameter_key=None, morphology_key=None):
+
+        """ If neuron_id is given, that neuron will be loaded."""
+
+        # print(f"Neuron cache size: {len(self.neuron_cache)}")
+
+        if neuron_id is not None and neuron_id in self.neuron_cache:
+            return self.neuron_cache[neuron_id]
+
+        if (neuron_path is not None and parameter_key is not None and morphology_key is not None
+                and (neuron_path, parameter_key, morphology_key) in self.neuron_cache):
+            return self.neuron_cache[(neuron_path, parameter_key, morphology_key)]
+
+        if neuron_id is not None and hdf5 is not None:
+            neuron_path = SnuddaLoad.to_str(hdf5["network/neurons/neuronPath"][neuron_id])
+            parameter_key = SnuddaLoad.to_str(hdf5["network/neurons/parameterKey"][neuron_id])
+            morphology_key = SnuddaLoad.to_str(hdf5["network/neurons/morphologyKey"][neuron_id])
+
+        assert neuron_path is not None and parameter_key is not None and morphology_key is not None, \
+            "Either provide neuron_id, hdf5 or the three neuron_path, parameter_key and morphology_key"
+
+        if neuron_id and hdf5:
+            pos = hdf5["network/neurons/position"][neuron_id, :]
+            rot = hdf5["network/neurons/rotation"][neuron_id, :].reshape(3, 3)
+        else:
+            pos = None
+            rot = None
+
+        neuron_prototype = NeuronPrototype(neuron_path=neuron_path, neuron_name=None)
+        neuron = neuron_prototype.clone(parameter_key=parameter_key, morphology_key=morphology_key,
+                                        position=pos, rotation=rot)
+
+        if neuron_id is not None:
+            self.neuron_cache[neuron_id] = neuron
+        else:
+            self.neuron_cache[(neuron_path, parameter_key, morphology_key)] = neuron
+
+        return neuron
+
+    def filter_synapses_helper(self, synapses):
+
+        """ This currently only takes DENDRITE degeneration into account.
+            AXON degeneration is not taken into account for synapse removal.
+        """
+
+        pre_id = synapses[0, 0]
+        post_id = synapses[0, 1]
+
+        assert (synapses[:, 0] == pre_id).all()
+        assert (synapses[:, 1] == post_id).all()
+
+        keep_synapses = np.ones((synapses.shape[0],), dtype=bool)
+
+        old_sec_id = synapses[:, 9]
+        old_sec_x = synapses[:, 10]
+
+        keep_idx, new_sec_id, new_sec_x \
+            = self.remap_sections_helper(neuron_id=post_id, old_sec_id=old_sec_id, old_sec_x=old_sec_x/1000)
+
+        edited_synapses = synapses.copy()
+
+        edited_synapses[:, 9] = new_sec_id
+        edited_synapses[:, 10] = new_sec_x * 1000
+
+        return edited_synapses[keep_idx, :]
+
+    def filter_gap_junctions_helper(self, gap_junctions):
+
+        # Gap junctions are bidirectional, but call them pre and post out of habit
+        pre_id = gap_junctions[0, 0]
+        post_id = gap_junctions[0, 1]
+
+        assert (gap_junctions[:, 0] == pre_id).all()
+        assert (gap_junctions[:, 1] == post_id).all()
+
+        old_pre_sec_id = gap_junctions[:, 2]
+        old_pre_sec_x = gap_junctions[:, 4]
+        old_post_sec_id = gap_junctions[:, 3]
+        old_post_sec_x = gap_junctions[:, 5]
+
+        keep_idx_pre, new_pre_sec_id, new_pre_sec_x \
+            = self.remap_sections_helper(neuron_id=pre_id, old_sec_id=old_pre_sec_id, old_sec_x=old_pre_sec_x/1000)
+
+        keep_idx_post, new_post_sec_id, new_post_sec_x \
+            = self.remap_sections_helper(neuron_id=post_id, old_sec_id=old_post_sec_id, old_sec_x=old_post_sec_x/1000)
+
+        keep_idx = np.intersect1d(keep_idx_pre, keep_idx_post)
+
+        edited_gap_junctions = gap_junctions.copy()
+        edited_gap_junctions[:, 2] = new_pre_sec_id
+        edited_gap_junctions[:, 3] = new_post_sec_id
+        edited_gap_junctions[:, 4] = new_pre_sec_x * 1000
+        edited_gap_junctions[:, 5] = new_post_sec_x * 1000
+
+        return edited_gap_junctions[keep_idx, :]
+
+    def find_old_morphology(self, neuron_id):
+
+        orig_morph_key = SnuddaLoad.to_str(self.old_data["neurons"][neuron_id]["morphologyKey"])
+        orig_param_key = SnuddaLoad.to_str(self.old_data["neurons"][neuron_id]["parameterKey"])
+        orig_neuron_path = SnuddaLoad.to_str(self.old_data["neurons"][neuron_id]["neuronPath"])
+
+        return orig_param_key, orig_morph_key, orig_neuron_path
+
+    def find_morpology(self, neuron_id):
+
+        """ Given neuron_id it looks up what was old morphology, then looks for a new morphology with the same name
+            and finds the corresponding morphology_key. It also tries to pick a parameter_key """
+
+        orig_morph_key = SnuddaLoad.to_str(self.old_data["neurons"][neuron_id]["morphologyKey"])
+        orig_param_key = SnuddaLoad.to_str(self.old_data["neurons"][neuron_id]["parameterKey"])
+
+        # We assume the new morphology is in the same relative path, but using a different SNUDDA_DATA
+        orig_neuron_path = SnuddaLoad.to_str(self.old_data["neurons"][neuron_id]["neuronPath"])
+        orig_simple_path = snudda_simplify_path(orig_neuron_path, os.path.realpath(self.original_snudda_data_dir))
+        new_neuron_path = snudda_parse_path(orig_simple_path, os.path.realpath(self.new_snudda_data_dir))
+
+        if orig_morph_key == '':
+            # Only a single morpholoy
+            return '', '', new_neuron_path
+
+        # Here we assume there is a meta.json file
+        with open(os.path.join(orig_neuron_path, "meta.json"), "r") as f:
+            orig_meta_info = json.load(f)
+
+        with open(os.path.join(new_neuron_path, "meta.json"), "r") as f:
+            new_meta_info = json.load(f)
+
+        # Find the parameter_key and morphology_key corresponding to the morphology used. Note that there might be
+        # multiple parameter_key:s valid for a morphology, so then we randomly pick one of those
+
+        orig_morph_name = orig_meta_info[orig_param_key][orig_morph_key]["morphology"]
+
+        possible_keys = []
+
+        for param_key, param_data in new_meta_info.items():
+            for morph_key, morph_data in param_data.items():
+                morph_name = morph_data["morphology"]
+                if orig_morph_name == morph_name:
+                    possible_keys.append((param_key, morph_key))
+
+        assert len(possible_keys) > 0, \
+            f"No morphology matching for {orig_morph_name}, unable to pick parameter_key and morphology_key"
+
+        # Pick one of the key pairs
+        idx = np.random.randint(low=0, high=len(possible_keys))
+        new_param_key, new_morph_key = possible_keys[idx]
+
+        # We also need parameter_id and morphology_id
+        parameter_id = np.where([x == new_param_key for x in new_meta_info.keys()])[0][0]
+        morphology_id = np.where([x == new_morph_key for x in new_meta_info[new_param_key].keys()])[0][0]
+
+        return new_param_key, new_morph_key, new_neuron_path, parameter_id, morphology_id
+
+    def get_sec_location(self, coords, neuron_path, parameter_key, morphology_key, max_dist=5e-6):
+
+        morph = self.get_morphology(neuron_path=neuron_path,
+                                    parameter_key=parameter_key,
+                                    morphology_key=morphology_key)
+
+        dend = self.get_kd_tree(morph, "dend")
+        sec_id = np.zeros((dend.shape[0],), dtype=int)
+        sec_x = np.zeros((dend.shape[0],))
+
+        coord_to_sec_id_x = dict()
+        for link, sec_id, sec_x in zip(morph.dend_links, morph.dend_sec_id, morph.dend_sec_x):
+            coord = morph.dend[link[1], :]
+
+            coord_to_sec_id_x[coord] = (sec_id, sec_x[1])
+
+        for idx, coord in enumerate(coords):
+            closest_dist, closest_point = dend.query(coord)
+
+            if closest_dist < max_dist:
+                syn_sec_id, syn_sec_x = coord_to_sec_id_x[morph.dend[closest_point, :3]]
+                sec_id[idx] = syn_sec_id
+                sec_x[idx] = syn_sec_x
+            else:
+                sec_id[idx] = np.nan
+                sec_x[idx] = np.nan
+
+        return sec_id, sec_x
+
+    def write_new_input_file(self):
+
+        if not os.path.isdir(os.path.dirname(self.new_input_file)):
+            os.mkdir(os.path.dirname(self.new_input_file))
+
+        print(f"Writing new input data to {self.new_input_file}")
+
+        old_input = h5py.File(self.original_input_file, "r")
+        new_input = h5py.File(self.new_input_file, "w")
+        old_input.copy(source=old_input["config"], dest=new_input)
+
+        new_input.create_group("input")
+
+        for neuron in old_input["input"].keys():
+            neuron_group = new_input["input"].create_group(neuron)
+
+            old_n = 0
+            new_n = 0
+
+            for input_type in old_input["input"][neuron].keys():
+                # Note: This code assumes these are real neuron and not just virtual neurons.
+                #       it does not handle the virtual neuron case here.
+                old_input_data = old_input["input"][neuron][input_type]
+
+                keep_idx, new_sec_id, new_sec_x \
+                    = self.remap_sections_helper(neuron_id=int(neuron),
+                                                 old_sec_id=old_input_data["sectionID"],
+                                                 old_sec_x=old_input_data["sectionX"])
+
+                if len(keep_idx) == 0:
+                    continue
+
+                input_group = neuron_group.create_group(input_type)
+
+                input_group.create_dataset("spikes", data=old_input_data["spikes"][keep_idx, :],
+                                           compression="gzip", dtype=np.float32)
+                input_group.create_dataset("nSpikes", data=old_input_data["nSpikes"][keep_idx], dtype=np.int32)
+                input_group.create_dataset("sectionID", data=new_sec_id[keep_idx], compression="gzip", dtype=np.int16)
+                input_group.create_dataset("sectionX", data=new_sec_x[keep_idx], compression="gzip", dtype=np.float16)
+
+                input_group.create_dataset("distanceToSoma", data=old_input_data["distanceToSoma"][keep_idx],
+                                           compression="gzip", dtype=np.float16)
+
+                for data_name in ["freq", "correlation", "jitter", "synapseDensity", "start", "end", "conductance",
+                                  "populationUnitID", "populationUnitSpikes", "generator",
+                                  "modFile", "parameterFile", "parameterList", "parameterID"]:
+                    if data_name in old_input_data:
+                        old_input_data.copy(source=old_input_data[data_name], dest=input_group)
+
+                old_n += old_input_data['spikes'].shape[0]
+                new_n += len(keep_idx)
+
+            print(f"Processed input to {self.old_data['neurons'][int(neuron)]['name']} ({neuron}), "
+                  f"keeping {new_n} out of {old_n} inputs "
+                  f"({new_n / old_n * 100 :.2f} %)")
+
+        old_input.close()
+        new_input.close()
+
+    def get_kd_tree(self, neuron, tree_type):
+
+        if (neuron, tree_type) not in self.kd_tree_cache:
+
+            coords = {"axon": neuron.axon[:, :3],
+                      "dend": neuron.dend[:, :3]}
+
+            if coords[tree_type].size > 0:
+                self.kd_tree_cache[(neuron, tree_type)] = KDTree(coords[tree_type])
+            else:
+                self.kd_tree_cache[(neuron, tree_type)] = None
+
+        return self.kd_tree_cache[(neuron, tree_type)]
+
+    def create_section_lookup(self):
+
+        for neuron_id in self.old_hdf5["network/neurons/neuronID"]:
+            self.create_section_lookup_helper(neuron_id)
+
+    # Note this does not take AXON degeneration into account, need to do that separately
+    def create_section_lookup_helper(self, neuron_id):
+
+        old_param_key, old_morph_key, old_path = self.find_old_morphology(neuron_id=neuron_id)
+        new_param_key, new_morph_key, new_path, _, _ = self.find_morpology(neuron_id=neuron_id)
+
+        if (old_param_key, old_morph_key, old_path) in self.section_lookup:
+            # We already have the morphology in the section_lookup
+            return
+
+        old_morph = self.get_morphology(parameter_key=old_param_key, morphology_key=old_morph_key, neuron_path=old_path)
+        new_morph = self.get_morphology(parameter_key=new_param_key, morphology_key=new_morph_key, neuron_path=new_path)
+
+        coord_to_sec_id_x = dict()
+        for link, old_sec_id, old_sec_x in zip(old_morph.dend_links, old_morph.dend_sec_id, old_morph.dend_sec_x):
+            coord = (old_morph.dend[link[1], :3] * 1e9).astype(int)
+
+            assert (coord[0], coord[1], coord[2]) not in coord_to_sec_id_x, \
+                f"Coordinates {(coord[0], coord[1], coord[2])} already exists in {coord_to_sec_id_x}"
+
+            coord_to_sec_id_x[coord[0], coord[1], coord[2]] = (old_sec_id, old_sec_x[1])
+
+        old_to_new_sec_id = dict()
+        old_sec_x_list = dict()
+        new_sec_x_list = dict()
+        # We just need to find the maximal old sec_x still present,
+                                 # that value will map to sec_x 1.0 in new (stored as int sec_x*1000)
+
+        for link, new_sec_id, new_sec_x in zip(new_morph.dend_links, new_morph.dend_sec_id, new_morph.dend_sec_x):
+            coord = (new_morph.dend[link[1], :3] * 1e9).astype(int)
+
+            try:
+                old_sec_id, old_sec_x = coord_to_sec_id_x[coord[0], coord[1], coord[2]]
+            except:
+                import traceback
+                print(traceback.format_exc())
+                print(f"Coordinate point in old file missing in new file.\n"
+                      f"Old morphology: {old_morph.swc_filename}\n"
+                      f"New morphology: {new_morph.swc_filename}")
+                import pdb
+                pdb.set_trace()
+
+            # TODO: What happens if a branch looses one of its side branches, will then those two sections
+            #       be merged into one? This code will then complain.
+
+            if old_sec_id in old_to_new_sec_id:
+                assert old_to_new_sec_id[old_sec_id] == new_sec_id, \
+                    (f"Old sec_id {old_sec_id} maps to multiple " 
+                     f"new sec_id {new_sec_id} and {old_to_new_sec_id[old_sec_id]}")
+            else:
+               old_to_new_sec_id[old_sec_id] = new_sec_id
+
+            if old_sec_id not in old_sec_x_list:
+                old_sec_x_list[old_sec_id] = [old_sec_x]
+                new_sec_x_list[old_sec_id] = [new_sec_x[1]]
+            else:
+                old_sec_x_list[old_sec_id].append(old_sec_x)
+                new_sec_x_list[old_sec_id].append(new_sec_x[1])
+
+        neuron_section_lookup = {0: (0, np.array([0, 1]), np.array([0, 1]))}  # Add SOMA mapping. ID 0-1 --> ID 0-1
+
+        for old_sec_id in old_to_new_sec_id.keys():
+
+            assert (np.diff(old_sec_x_list[old_sec_id]) > 0).all()
+            assert (np.diff(new_sec_x_list[old_sec_id]) > 0).all()
+
+            neuron_section_lookup[old_sec_id] = (old_to_new_sec_id[old_sec_id],
+                                                 np.array(old_sec_x_list[old_sec_id]),
+                                                 np.array(new_sec_x_list[old_sec_id]))
+
+        assert len(neuron_section_lookup) > 10, (f"Section lookup has fewer than 10 elements. Does morphologies match?"
+                                                 f"\nOld = {old_path, old_param_key, old_morph_key}"
+                                                 f"\nNew = {new_path, new_param_key, new_morph_key}")
+
+            # Check that all new_coords exist in the old_coords list.
+
+        self.section_lookup[old_param_key, old_morph_key, old_path] = neuron_section_lookup
+
+    def remap_sections_helper(self, neuron_id, old_sec_id, old_sec_x):
+
+        """
+            Remaps sections for neuron_id
+
+            This does currently NOT take AXON DEGENERATION into account
+
+            Args:
+                neuron_id (int) : Neuron ID
+                old_sec_id (np.array) : Section ID of old section
+                old_sec_x (np.array) : Section X of old section (float 0-1)
+
+            Returns:
+                keep_idx (np.array) : Indexes to keep
+                new_sec_id (np.array) : Section ID of new section, positions are np.nan if not mapped
+                new_sec_x (np.array) : Section X of new section, positions are np.nan if not mapped
+
+        """
+
+        keep_idx = np.zeros(old_sec_id.shape, dtype=bool)
+        new_sec_id = np.zeros(old_sec_id.shape, dtype=int) * np.nan
+        new_sec_x = np.zeros(old_sec_id.shape) * np.nan
+
+        old_param_key, old_morph_key, old_path = self.find_old_morphology(neuron_id=neuron_id)
+
+        lookup = self.section_lookup[old_param_key, old_morph_key, old_path]
+
+        for idx, (old_id, old_x) in enumerate(zip(old_sec_id, old_sec_x)):
+            if old_id in lookup:
+                new_id = lookup[old_id][0]
+
+                # We know range of old x that are still valid, and new x they map to. If outside, returns nan
+                try:
+                    new_x = np.interp(old_x, lookup[old_id][1], lookup[old_id][2], right=np.nan, left=np.nan)
+                except:
+                    import traceback
+                    print(traceback.format_exc())
+                    import pdb
+                    pdb.set_trace()
+
+                if not np.isnan(new_x):
+                    assert 0 <= new_x <= 1, f"Out of range new_x={new_x} (required 0-1)"
+
+                    keep_idx[idx] = True
+                    new_sec_id[idx] = new_id
+                    new_sec_x[idx] = new_x
+
+        return np.where(keep_idx)[0], new_sec_id, new_sec_x
+
+
+def cli():
+    parser = ArgumentParser(
+        description="Replace WT morphologies with PD morphologies, remove orphaned synapses and input",
+        formatter_class=RawTextHelpFormatter)
+
+    parser.add_argument("original_network_path", type=str)
+    parser.add_argument("new_network_path", type=str)
+    parser.add_argument("original_snudda_path", type=str)
+    parser.add_argument("new_snudda_path", type=str)
+
+    args = parser.parse_args()
+
+    if not os.path.isdir(args.new_network_path):
+        os.mkdir(args.new_network_path)
+
+    original_network_file = os.path.join(args.original_network_path, "network-synapses.hdf5")
+    new_network_file = os.path.join(args.new_network_path, "network-synapses.hdf5")
+    original_input_file = os.path.join(args.original_network_path, "input-spikes.hdf5")
+    new_input_file = os.path.join(args.new_network_path, "input-spikes.hdf5")
+
+    swap = SwapToDegenerateMorphologies(original_network_file=original_network_file,
+                                        new_network_file=new_network_file,
+                                        original_snudda_data_dir=args.original_snudda_path,
+                                        new_snudda_data_dir=args.new_snudda_path,
+                                        original_input_file=original_input_file,
+                                        new_input_file=new_input_file)
+    swap.write_new_network_file()
+    swap.write_new_input_file()
+
+    swap.close()
+
+
+if __name__ == "__main__":
+    cli()
diff --git a/snudda/utils/upgrade_old_network_file.py b/snudda/utils/upgrade_old_network_file.py
index 0067e2e7e..feabcbc92 100755
--- a/snudda/utils/upgrade_old_network_file.py
+++ b/snudda/utils/upgrade_old_network_file.py
@@ -3,7 +3,6 @@
 
 
 def upgrade_old_network_file(file_name):
-
     """ Adds morphologyID filed if missing to network_file """
 
     print(f"Opening {file_name}")
@@ -41,11 +40,10 @@ def upgrade_old_network_file(file_name):
 
 
 if __name__ == "__main__":
-
     from argparse import ArgumentParser
+
     parser = ArgumentParser(description="Upgrade snudda network file (hdf5), adding missing morphologyID field")
     parser.add_argument("network_file", help="Network file (hdf5)", type=str)
     args = parser.parse_args()
 
     upgrade_old_network_file(args.network_file)
-


Test patch:
diff --git a/tests/test_cli.py b/tests/test_cli.py
index 1a07f23a6..c2f0a51a0 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -1,4 +1,8 @@
-import unittest, os, sys, argparse, time
+import argparse
+import os
+import sys
+import time
+import unittest
 
 sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
 import snudda.cli
@@ -114,12 +118,7 @@ def test_workflow(self):
             print(f"Running: {eval_str}")
             os.system(eval_str)
 
-            # print("---> Testing to run simulate using os.system instead")
-            # os.system("snudda simulate tiny_parallel --time 0.1")
-
-
-            # For the unittest we for some reason need to load mechansism
-            # separately
+            # For the unittest we for some reason need to load mechansism separately
             from mpi4py import MPI  # This must be imported before neuron, to run parallel
             from neuron import h  # , gui
             import neuron
@@ -135,19 +134,6 @@ def test_workflow(self):
                     tstr = traceback.format_exc()
                     print(tstr)
 
-            if False:
-                try:
-                    from snudda.simulate.simulate import SnuddaSimulate
-                    ss = SnuddaSimulate(network_path="tiny_parallel")
-                    ss.run(100)
-                    ss.write_spikes()
-                except:
-                    import traceback
-                    tstr = traceback.format_exc()
-                    print(tstr)
-                    import pdb
-                    pdb.set_trace()
-                
             print("Time to run simulation...")
             run_cli_command("simulate tiny_parallel --time 0.1")
 
diff --git a/tests/test_detect.py b/tests/test_detect.py
index 5823d9649..4a8ced89b 100644
--- a/tests/test_detect.py
+++ b/tests/test_detect.py
@@ -1,10 +1,11 @@
-import unittest
 import os
 import sys
+import unittest
+
 import numpy as np
 
-from snudda.place.create_cube_mesh import create_cube_mesh
 from snudda.detect.detect import SnuddaDetect
+from snudda.place.create_cube_mesh import create_cube_mesh
 from snudda.place.place import SnuddaPlace
 
 sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
@@ -40,7 +41,7 @@ def setUp(self):
 
     def test_detect(self):
 
-        neuron_positions = np.array([[0, 20, 0],    # Postsynaptiska
+        neuron_positions = np.array([[0, 20, 0],  # Postsynaptiska
                                      [0, 40, 0],
                                      [0, 60, 0],
                                      [0, 80, 0],
@@ -50,7 +51,7 @@ def test_detect(self):
                                      [0, 160, 0],
                                      [0, 180, 0],
                                      [0, 200, 0],
-                                     [20, 0, 0],    # Presynaptiska
+                                     [20, 0, 0],  # Presynaptiska
                                      [40, 0, 0],
                                      [60, 0, 0],
                                      [80, 0, 0],
@@ -61,30 +62,30 @@ def test_detect(self):
                                      [180, 0, 0],
                                      [200, 0, 0],
                                      [100, 100, -40],  # To get a gap junction
-                                     ])*1e-6
+                                     ]) * 1e-6
 
         for idx, pos in enumerate(neuron_positions):
             self.sd.neurons[idx]["position"] = pos
 
-        ang = -np.pi/2
+        ang = -np.pi / 2
         R_x = np.array([[1, 0, 0],
                         [0, np.cos(ang), -np.sin(ang)],
                         [0, np.sin(ang), np.cos(ang)]])
 
-        ang = np.pi/2
+        ang = np.pi / 2
         R_y = np.array([[np.cos(ang), 0, np.sin(ang)],
                         [0, 1, 0],
                         [-np.sin(ang), 0, np.cos(ang)]])
 
-        ang = -np.pi/2
+        ang = -np.pi / 2
         R_gj = np.array([[np.cos(ang), 0, np.sin(ang)],
                          [0, 1, 0],
                          [-np.sin(ang), 0, np.cos(ang)]])
 
-        for idx in range(0, 10):    # Post synaptic neurons
+        for idx in range(0, 10):  # Post synaptic neurons
             self.sd.neurons[idx]["rotation"] = R_x
 
-        for idx in range(10, 20):   # Presynaptic neurons
+        for idx in range(10, 20):  # Presynaptic neurons
             self.sd.neurons[idx]["rotation"] = R_y
 
         self.sd.neurons[20]["rotation"] = R_gj
@@ -99,7 +100,7 @@ def test_detect(self):
         if not os.path.exists(fig_path):
             os.mkdir(fig_path)
 
-        if False:   # Set to True to include plot
+        if False:  # Set to True to include plot
             self.sd.plot_hyper_voxel(plot_neurons=True, fig_file_name="touch-detection-validation")
 
         # TODO: Also add tests for soma-axon synapses
@@ -109,7 +110,7 @@ def test_detect(self):
             self.assertEqual(self.sd.hyper_voxel_gap_junction_ctr, 1)
             self.assertTrue((self.sd.hyper_voxel_gap_junctions[0, 0:2] == [4, 20]).all())
             self.assertTrue(self.compare_voxels_to_coordinates(self.sd.hyper_voxel_gap_junctions[0, 6:9],
-                                                               np.array([100, 100, 0])*1e-6))
+                                                               np.array([100, 100, 0]) * 1e-6))
         with self.subTest(stage="synapses_check"):
             print(f"synapse ctr {self.sd.hyper_voxel_synapse_ctr}")
 
@@ -129,12 +130,12 @@ def test_detect(self):
 
         with self.subTest(stage="synapse_sorting_check"):
             syn = self.sd.hyper_voxel_synapses[:self.sd.hyper_voxel_synapse_ctr, :2]
-            syn_order = syn[:, 1]*len(self.sd.neurons) + syn[:, 0]
+            syn_order = syn[:, 1] * len(self.sd.neurons) + syn[:, 0]
             self.assertTrue((np.diff(syn_order) >= 0).all())
 
         with self.subTest(stage="gap_junction_sorting_check"):
             gj = self.sd.hyper_voxel_gap_junctions[:self.sd.hyper_voxel_gap_junction_ctr, :2]
-            gj_order = gj[:, 1]*len(self.sd.neurons) + gj[:, 0]
+            gj_order = gj[:, 1] * len(self.sd.neurons) + gj[:, 0]
             self.assertTrue((np.diff(gj_order) >= 0).all())
 
         with self.subTest(stage="synapse_conductance_check"):
@@ -209,7 +210,7 @@ def test_detect_lines(self):
         # id 0-9 connecting to id 10-19, connection angle is 0-45 degrees
         # id 20 is 4 micrometer and parallel to another dendrite, no intersection
 
-        neuron_positions = np.array([[0, 0, 0],    # Postsynaptiska
+        neuron_positions = np.array([[0, 0, 0],  # Postsynaptiska
                                      [10, 10, 15],
                                      [20, 20, 30],
                                      [30, 30, 45],
@@ -219,7 +220,7 @@ def test_detect_lines(self):
                                      [70, 70, 105],
                                      [80, 80, 120],
                                      [90, 90, 135],
-                                     [50, -100, 0],    # Presynaptiska
+                                     [50, -100, 0],  # Presynaptiska
                                      [60, -90, 15],
                                      [70, -80, 30],
                                      [80, -70, 45],
@@ -230,25 +231,25 @@ def test_detect_lines(self):
                                      [130, -20, 120],
                                      [140, -10, 135],
                                      [230, 0, 4],  # 4 micrometers from first neuron
-                                     ])*1e-6
+                                     ]) * 1e-6
 
         for idx, pos in enumerate(neuron_positions):
             self.sd.neurons[idx]["position"] = pos
 
-        ang = -np.pi/2
+        ang = -np.pi / 2
         R_x = np.array([[1, 0, 0],
                         [0, np.cos(ang), -np.sin(ang)],
                         [0, np.sin(ang), np.cos(ang)]])
 
-        ang = np.pi/2
+        ang = np.pi / 2
         R_y = np.array([[np.cos(ang), 0, np.sin(ang)],
                         [0, 1, 0],
                         [-np.sin(ang), 0, np.cos(ang)]])
 
-        for idx in range(0, 10):    # Post synaptic neurons
+        for idx in range(0, 10):  # Post synaptic neurons
             self.sd.neurons[idx]["rotation"] = R_x
 
-        for idx, ang in zip(range(10, 20), np.linspace(0, -np.pi/4, 10)):   # Presynaptic neurons
+        for idx, ang in zip(range(10, 20), np.linspace(0, -np.pi / 4, 10)):  # Presynaptic neurons
 
             R_z = np.array([[np.cos(ang), -np.sin(ang), 0],
                             [np.sin(ang), np.cos(ang), 0],
@@ -270,7 +271,7 @@ def test_detect_lines(self):
         synapse_voxel_loc = self.sd.hyper_voxel_synapses[:self.sd.hyper_voxel_synapse_ctr, 2:5]
         synapse_coords = synapse_voxel_loc * self.sd.voxel_size + self.sd.hyper_voxel_origo
 
-        if False:   # Set to True to include plot
+        if False:  # Set to True to include plot
             self.sd.plot_hyper_voxel(plot_neurons=True, fig_file_name="axon_dend_intersection_angle_0_45")
 
         with self.subTest(stage="synapses_check"):
@@ -290,4 +291,3 @@ def test_detect_lines(self):
     unittest.main()
 
 # python3 -m unittest test_detect
-    
diff --git a/tests/test_input.py b/tests/test_input.py
index 574ae1220..111f9b852 100644
--- a/tests/test_input.py
+++ b/tests/test_input.py
@@ -258,5 +258,6 @@ def test_input_1(self):
 
                         pdb.set_trace()
 
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/tests/test_modify_network.py b/tests/test_modify_network.py
index 372090a45..82dc42e86 100644
--- a/tests/test_modify_network.py
+++ b/tests/test_modify_network.py
@@ -26,7 +26,7 @@ def setUp(self) -> None:
         if not os.path.exists(self.original_file):
             print("Missing test network, generating it first.")
             from snudda.init import SnuddaInit
-            SnuddaInit(network_path=self.network_path, struct_def={"Striatum": 200})
+            SnuddaInit(network_path=self.network_path, struct_def={"Striatum": 200}, random_seed=999)
 
             from snudda.place import SnuddaPlace
             sp = SnuddaPlace(network_path=self.network_path)
diff --git a/tests/test_segmentid.py b/tests/test_segmentid.py
index da209ef28..e14e6466b 100644
--- a/tests/test_segmentid.py
+++ b/tests/test_segmentid.py
@@ -37,6 +37,8 @@ def test_segment_id_numbering(self, morph_file=None):
         print(f"Loading neuron {morph_file}")
         snudda_neuron = NeuronMorphology(name="fs", swc_filename=morph_file, use_cache=False)
 
+        self.assertTrue((snudda_neuron.soma[0, :3] == 0).all(), f"Soma should be centered for {morph_file}.")
+
         # Load morphology into NEURON
         neuron_model = NeuronModel(param_file=os.path.join("data", "fake-parameters.json"),
                                    morph_path=morph_file,