diff --git a/CMakeLists.txt b/CMakeLists.txt
index 37f1cfe80e468fa7d8c50a7f57ab7de7b01a2f51..44e40b639c2328b5512ad4c557a877d4d9cbec8f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -62,6 +62,12 @@ if(SYSTEM_CRAY)
     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -dynamic")
 endif()
 
+# Cray systems
+set(TARGET_KNL OFF CACHE BOOL "target Intel KNL architecture")
+if(TARGET_KNL)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXXOPT_KNL}")
+endif()
+
 # targets for extermal dependencies
 include(ExternalProject)
 externalproject_add(modparser
diff --git a/cmake/CompilerOptions.cmake b/cmake/CompilerOptions.cmake
index 167ae04818f6c2eb791704de08d7bd99adb449fb..6dc09b961cc6a71ce69b1bf9cba5d6821e6949e8 100644
--- a/cmake/CompilerOptions.cmake
+++ b/cmake/CompilerOptions.cmake
@@ -13,10 +13,21 @@ if(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
     set(CXXOPT_WALL "${CXXOPT_WALL} -Wno-missing-braces")
 endif()
 
+if(${CMAKE_CXX_COMPILER_ID} MATCHES "GNU")
+
+    # compiler flags for generating KNL-specific AVX512 instructions
+    # supported in gcc 4.9.x and later
+    #set(CXXOPT_KNL "-mavx512f")
+    set(CXXOPT_KNL "-march=knl")
+endif()
+
 if(${CMAKE_CXX_COMPILER_ID} MATCHES "Intel")
     # Disable warning for unused template parameter
     # this is raised by a templated function in the json library
 
     set(CXXOPT_WALL "${CXXOPT_WALL} -wd488")
+
+    # compiler flags for generating KNL-specific AVX512 instructions
+    set(CXXOPT_KNL "-xMIC-AVX512")
 endif()
 
diff --git a/data/cells_small.json b/data/cells_small.json
index 01dc71bd84eb623c4a682d45e9665732d36ad57e..93c8c2f3dc3078471f337b0bb2eebc231d78364e 100644
--- a/data/cells_small.json
+++ b/data/cells_small.json
@@ -60,7 +60,7 @@
   "indexes": [1,3,5,6,7,9,11,13,15,17,19,21,23,24,25,27,28,29,30,31,32,33,35,36,37,38,39,41,43,45,47,49,50,51,53,54,55,57,58,59,60,61,63,64,65,67,68,69,71,73],
   "name": "pas"
  }],
- "parent_index": [0,0,1,0,3,0,5,6,7,0,9,2,11,10,13,10,15,12,17,14,19,14,21,16,23,24,25,16,27,28,29,30,31,32,33,20,35,36,37,38,39,20,41,26,43,26,45,42,47,42,49,50,51,48,53,54,55,48,57,58,59,60,61,62,63,64,65,62,67,68,69,70,71,70,73]
+ "parent_index": [0,0,1,0,3,0,5,6,7,0,9,0,11,10,13,10,15,0,17,14,19,14,21,16,23,24,25,16,27,28,29,30,31,32,33,20,35,36,37,38,39,20,41,26,43,26,45,42,47,42,49,50,51,48,53,54,55,48,57,58,59,60,61,62,63,64,65,62,67,68,69,70,71,70,73]
 },{
  "mechanisms": [{
   "indexes": [1,11,17],
@@ -123,7 +123,7 @@
   "indexes": [1,3,5,6,7,9,11,13,15,17,19,21,23,24,25,27,28,29,30,31,32,33,35,36,37,38,39,41,43,45,47,49,50,51,53,54,55,57,58,59,60,61,63,64,65,67,68,69,71,73],
   "name": "pas"
  }],
- "parent_index": [0,0,1,0,3,0,5,6,7,0,9,2,11,10,13,10,15,12,17,14,19,14,21,16,23,24,25,16,27,28,29,30,31,32,33,20,35,36,37,38,39,20,41,26,43,26,45,42,47,42,49,50,51,48,53,54,55,48,57,58,59,60,61,62,63,64,65,62,67,68,69,70,71,70,73]
+ "parent_index": [0,0,1,0,3,0,5,6,7,0,9,0,11,10,13,10,15,0,17,14,19,14,21,16,23,24,25,16,27,28,29,30,31,32,33,20,35,36,37,38,39,20,41,26,43,26,45,42,47,42,49,50,51,48,53,54,55,48,57,58,59,60,61,62,63,64,65,62,67,68,69,70,71,70,73]
 },{
  "mechanisms": [{
   "indexes": [1,11,17],
@@ -186,7 +186,7 @@
   "indexes": [1,3,5,6,7,9,11,13,15,17,19,21,23,24,25,27,28,29,30,31,32,33,35,36,37,38,39,41,43,45,47,49,50,51,53,54,55,57,58,59,60,61,63,64,65,67,68,69,71,73],
   "name": "pas"
  }],
- "parent_index": [0,0,1,0,3,0,5,6,7,0,9,2,11,10,13,10,15,12,17,14,19,14,21,16,23,24,25,16,27,28,29,30,31,32,33,20,35,36,37,38,39,20,41,26,43,26,45,42,47,42,49,50,51,48,53,54,55,48,57,58,59,60,61,62,63,64,65,62,67,68,69,70,71,70,73]
+ "parent_index": [0,0,1,0,3,0,5,6,7,0,9,0,11,10,13,10,15,0,17,14,19,14,21,16,23,24,25,16,27,28,29,30,31,32,33,20,35,36,37,38,39,20,41,26,43,26,45,42,47,42,49,50,51,48,53,54,55,48,57,58,59,60,61,62,63,64,65,62,67,68,69,70,71,70,73]
 },{
  "mechanisms": [{
   "indexes": [1,11,17],
@@ -249,7 +249,7 @@
   "indexes": [1,3,5,6,7,9,11,13,15,17,19,21,23,24,25,27,28,29,30,31,32,33,35,36,37,38,39,41,43,45,47,49,50,51,53,54,55,57,58,59,60,61,63,64,65,67,68,69,71,73],
   "name": "pas"
  }],
- "parent_index": [0,0,1,0,3,0,5,6,7,0,9,2,11,10,13,10,15,12,17,14,19,14,21,16,23,24,25,16,27,28,29,30,31,32,33,20,35,36,37,38,39,20,41,26,43,26,45,42,47,42,49,50,51,48,53,54,55,48,57,58,59,60,61,62,63,64,65,62,67,68,69,70,71,70,73]
+ "parent_index": [0,0,1,0,3,0,5,6,7,0,9,0,11,10,13,10,15,0,17,14,19,14,21,16,23,24,25,16,27,28,29,30,31,32,33,20,35,36,37,38,39,20,41,26,43,26,45,42,47,42,49,50,51,48,53,54,55,48,57,58,59,60,61,62,63,64,65,62,67,68,69,70,71,70,73]
 },{
  "mechanisms": [{
   "indexes": [1,23,59],
@@ -312,7 +312,7 @@
   "indexes": [1,3,5,7,9,10,11,13,14,15,16,17,18,19,21,23,25,26,27,29,31,33,35,37,39,41,42,43,44,45,47,49,50,51,52,53,54,55,56,57,59,61,62,63,65,67,68,69,70,71,73,75,77,79,80,81,83,84,85,87,89,90,91,92,93,95,97,98,99,101,103,104,105,107,109,111,113,115,117,118,119,121,123,125,127,128,129,130,131,133,134,135,136,137,139,140,141,143,144,145,147,148,149,150,151,153,154,155,157,158,159,160,161,163,165,166,167,168,169,170,171,173,174,175,176,177,179,180,181,183,185,186,187,188,189,191,193,194,195,196,197,199,201,202,203,204,205,206,207,209,210,211,212,213,214,215,217,218,219,220,221,222,223,225,226,227,229,230,231,233,234,235,237,239,240,241,243,244,245,246,247,249,250,251,253,254,255,256,257,258,259,261,262,263,264,265,267,268,269,270,271,272,273,274,275,277,278,279,281,282,283,284,285,287,289,290,291,293,294,295,296,297,299,300,301,303,304,305,307,309,311,312,313,315,316,317,318,319,321,323,325,326,327,329,331,332,333,335,336,337,338,339,340,341,343,344,345,346,347,348,349,351,352,353,355,356,357,359,360,361,363],
   "name": "pas"
  }],
- "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,0,13,14,15,16,17,18,19,0,21,2,23,4,25,26,27,4,29,6,31,6,33,8,35,8,37,12,39,12,41,42,43,44,45,22,47,22,49,50,51,52,53,54,55,56,57,24,59,28,61,62,63,28,65,30,67,68,69,70,71,30,73,32,75,32,77,34,79,80,81,34,83,84,85,36,87,36,89,90,91,92,93,38,95,38,97,98,99,40,101,40,103,104,105,48,107,48,109,74,111,74,113,76,115,76,117,118,119,78,121,78,123,88,125,88,127,128,129,130,131,96,133,134,135,136,137,96,139,140,141,100,143,144,145,100,147,148,149,150,151,108,153,154,155,108,157,158,159,160,161,110,163,110,165,166,167,168,169,170,171,112,173,174,175,176,177,112,179,180,181,114,183,114,185,186,187,188,189,116,191,116,193,194,195,196,197,122,199,122,201,202,203,204,205,206,207,124,209,210,211,212,213,214,215,124,217,218,219,220,221,222,223,126,225,226,227,126,229,230,231,142,233,234,235,142,237,164,239,240,241,164,243,244,245,246,247,184,249,250,251,184,253,254,255,256,257,258,259,190,261,262,263,264,265,190,267,268,269,270,271,272,273,274,275,192,277,278,279,192,281,282,283,284,285,200,287,200,289,290,291,276,293,294,295,296,297,276,299,300,301,280,303,304,305,280,307,288,309,288,311,312,313,298,315,316,317,318,319,298,321,302,323,302,325,326,327,322,329,322,331,332,333,324,335,336,337,338,339,340,341,324,343,344,345,346,347,348,349,328,351,352,353,328,355,356,357,330,359,360,361,330,363]
+ "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,0,13,14,15,16,17,18,19,0,21,0,23,4,25,26,27,4,29,6,31,6,33,8,35,8,37,12,39,12,41,42,43,44,45,22,47,22,49,50,51,52,53,54,55,56,57,0,59,28,61,62,63,28,65,30,67,68,69,70,71,30,73,32,75,32,77,34,79,80,81,34,83,84,85,36,87,36,89,90,91,92,93,38,95,38,97,98,99,40,101,40,103,104,105,48,107,48,109,74,111,74,113,76,115,76,117,118,119,78,121,78,123,88,125,88,127,128,129,130,131,96,133,134,135,136,137,96,139,140,141,100,143,144,145,100,147,148,149,150,151,108,153,154,155,108,157,158,159,160,161,110,163,110,165,166,167,168,169,170,171,112,173,174,175,176,177,112,179,180,181,114,183,114,185,186,187,188,189,116,191,116,193,194,195,196,197,122,199,122,201,202,203,204,205,206,207,124,209,210,211,212,213,214,215,124,217,218,219,220,221,222,223,126,225,226,227,126,229,230,231,142,233,234,235,142,237,164,239,240,241,164,243,244,245,246,247,184,249,250,251,184,253,254,255,256,257,258,259,190,261,262,263,264,265,190,267,268,269,270,271,272,273,274,275,192,277,278,279,192,281,282,283,284,285,200,287,200,289,290,291,276,293,294,295,296,297,276,299,300,301,280,303,304,305,280,307,288,309,288,311,312,313,298,315,316,317,318,319,298,321,302,323,302,325,326,327,322,329,322,331,332,333,324,335,336,337,338,339,340,341,324,343,344,345,346,347,348,349,328,351,352,353,328,355,356,357,330,359,360,361,330,363]
 },{
  "mechanisms": [{
   "indexes": [1,23,59],
@@ -375,7 +375,7 @@
   "indexes": [1,3,5,7,9,10,11,13,14,15,16,17,18,19,21,23,25,26,27,29,31,33,35,37,39,41,42,43,44,45,47,49,50,51,52,53,54,55,56,57,59,61,62,63,65,67,68,69,70,71,73,75,77,79,80,81,83,84,85,87,89,90,91,92,93,95,97,98,99,101,103,104,105,107,109,111,113,115,117,118,119,121,123,125,127,128,129,130,131,133,134,135,136,137,139,140,141,143,144,145,147,148,149,150,151,153,154,155,157,158,159,160,161,163,165,166,167,168,169,170,171,173,174,175,176,177,179,180,181,183,185,186,187,188,189,191,193,194,195,196,197,199,201,202,203,204,205,206,207,209,210,211,212,213,214,215,217,218,219,220,221,222,223,225,226,227,229,230,231,233,234,235,237,239,240,241,243,244,245,246,247,249,250,251,253,254,255,256,257,258,259,261,262,263,264,265,267,268,269,270,271,272,273,274,275,277,278,279,281,282,283,284,285,287,289,290,291,293,294,295,296,297,299,300,301,303,304,305,307,309,311,312,313,315,316,317,318,319,321,323,325,326,327,329,331,332,333,335,336,337,338,339,340,341,343,344,345,346,347,348,349,351,352,353,355,356,357,359,360,361,363],
   "name": "pas"
  }],
- "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,0,13,14,15,16,17,18,19,0,21,2,23,4,25,26,27,4,29,6,31,6,33,8,35,8,37,12,39,12,41,42,43,44,45,22,47,22,49,50,51,52,53,54,55,56,57,24,59,28,61,62,63,28,65,30,67,68,69,70,71,30,73,32,75,32,77,34,79,80,81,34,83,84,85,36,87,36,89,90,91,92,93,38,95,38,97,98,99,40,101,40,103,104,105,48,107,48,109,74,111,74,113,76,115,76,117,118,119,78,121,78,123,88,125,88,127,128,129,130,131,96,133,134,135,136,137,96,139,140,141,100,143,144,145,100,147,148,149,150,151,108,153,154,155,108,157,158,159,160,161,110,163,110,165,166,167,168,169,170,171,112,173,174,175,176,177,112,179,180,181,114,183,114,185,186,187,188,189,116,191,116,193,194,195,196,197,122,199,122,201,202,203,204,205,206,207,124,209,210,211,212,213,214,215,124,217,218,219,220,221,222,223,126,225,226,227,126,229,230,231,142,233,234,235,142,237,164,239,240,241,164,243,244,245,246,247,184,249,250,251,184,253,254,255,256,257,258,259,190,261,262,263,264,265,190,267,268,269,270,271,272,273,274,275,192,277,278,279,192,281,282,283,284,285,200,287,200,289,290,291,276,293,294,295,296,297,276,299,300,301,280,303,304,305,280,307,288,309,288,311,312,313,298,315,316,317,318,319,298,321,302,323,302,325,326,327,322,329,322,331,332,333,324,335,336,337,338,339,340,341,324,343,344,345,346,347,348,349,328,351,352,353,328,355,356,357,330,359,360,361,330,363]
+ "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,0,13,14,15,16,17,18,19,0,21,0,23,4,25,26,27,4,29,6,31,6,33,8,35,8,37,12,39,12,41,42,43,44,45,22,47,22,49,50,51,52,53,54,55,56,57,0,59,28,61,62,63,28,65,30,67,68,69,70,71,30,73,32,75,32,77,34,79,80,81,34,83,84,85,36,87,36,89,90,91,92,93,38,95,38,97,98,99,40,101,40,103,104,105,48,107,48,109,74,111,74,113,76,115,76,117,118,119,78,121,78,123,88,125,88,127,128,129,130,131,96,133,134,135,136,137,96,139,140,141,100,143,144,145,100,147,148,149,150,151,108,153,154,155,108,157,158,159,160,161,110,163,110,165,166,167,168,169,170,171,112,173,174,175,176,177,112,179,180,181,114,183,114,185,186,187,188,189,116,191,116,193,194,195,196,197,122,199,122,201,202,203,204,205,206,207,124,209,210,211,212,213,214,215,124,217,218,219,220,221,222,223,126,225,226,227,126,229,230,231,142,233,234,235,142,237,164,239,240,241,164,243,244,245,246,247,184,249,250,251,184,253,254,255,256,257,258,259,190,261,262,263,264,265,190,267,268,269,270,271,272,273,274,275,192,277,278,279,192,281,282,283,284,285,200,287,200,289,290,291,276,293,294,295,296,297,276,299,300,301,280,303,304,305,280,307,288,309,288,311,312,313,298,315,316,317,318,319,298,321,302,323,302,325,326,327,322,329,322,331,332,333,324,335,336,337,338,339,340,341,324,343,344,345,346,347,348,349,328,351,352,353,328,355,356,357,330,359,360,361,330,363]
 },{
  "mechanisms": [{
   "indexes": [1,23,59],
@@ -438,7 +438,7 @@
   "indexes": [1,3,5,7,9,10,11,13,14,15,16,17,18,19,21,23,25,26,27,29,31,33,35,37,39,41,42,43,44,45,47,49,50,51,52,53,54,55,56,57,59,61,62,63,65,67,68,69,70,71,73,75,77,79,80,81,83,84,85,87,89,90,91,92,93,95,97,98,99,101,103,104,105,107,109,111,113,115,117,118,119,121,123,125,127,128,129,130,131,133,134,135,136,137,139,140,141,143,144,145,147,148,149,150,151,153,154,155,157,158,159,160,161,163,165,166,167,168,169,170,171,173,174,175,176,177,179,180,181,183,185,186,187,188,189,191,193,194,195,196,197,199,201,202,203,204,205,206,207,209,210,211,212,213,214,215,217,218,219,220,221,222,223,225,226,227,229,230,231,233,234,235,237,239,240,241,243,244,245,246,247,249,250,251,253,254,255,256,257,258,259,261,262,263,264,265,267,268,269,270,271,272,273,274,275,277,278,279,281,282,283,284,285,287,289,290,291,293,294,295,296,297,299,300,301,303,304,305,307,309,311,312,313,315,316,317,318,319,321,323,325,326,327,329,331,332,333,335,336,337,338,339,340,341,343,344,345,346,347,348,349,351,352,353,355,356,357,359,360,361,363],
   "name": "pas"
  }],
- "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,0,13,14,15,16,17,18,19,0,21,2,23,4,25,26,27,4,29,6,31,6,33,8,35,8,37,12,39,12,41,42,43,44,45,22,47,22,49,50,51,52,53,54,55,56,57,24,59,28,61,62,63,28,65,30,67,68,69,70,71,30,73,32,75,32,77,34,79,80,81,34,83,84,85,36,87,36,89,90,91,92,93,38,95,38,97,98,99,40,101,40,103,104,105,48,107,48,109,74,111,74,113,76,115,76,117,118,119,78,121,78,123,88,125,88,127,128,129,130,131,96,133,134,135,136,137,96,139,140,141,100,143,144,145,100,147,148,149,150,151,108,153,154,155,108,157,158,159,160,161,110,163,110,165,166,167,168,169,170,171,112,173,174,175,176,177,112,179,180,181,114,183,114,185,186,187,188,189,116,191,116,193,194,195,196,197,122,199,122,201,202,203,204,205,206,207,124,209,210,211,212,213,214,215,124,217,218,219,220,221,222,223,126,225,226,227,126,229,230,231,142,233,234,235,142,237,164,239,240,241,164,243,244,245,246,247,184,249,250,251,184,253,254,255,256,257,258,259,190,261,262,263,264,265,190,267,268,269,270,271,272,273,274,275,192,277,278,279,192,281,282,283,284,285,200,287,200,289,290,291,276,293,294,295,296,297,276,299,300,301,280,303,304,305,280,307,288,309,288,311,312,313,298,315,316,317,318,319,298,321,302,323,302,325,326,327,322,329,322,331,332,333,324,335,336,337,338,339,340,341,324,343,344,345,346,347,348,349,328,351,352,353,328,355,356,357,330,359,360,361,330,363]
+ "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,0,13,14,15,16,17,18,19,0,21,0,23,4,25,26,27,4,29,6,31,6,33,8,35,8,37,12,39,12,41,42,43,44,45,22,47,22,49,50,51,52,53,54,55,56,57,0,59,28,61,62,63,28,65,30,67,68,69,70,71,30,73,32,75,32,77,34,79,80,81,34,83,84,85,36,87,36,89,90,91,92,93,38,95,38,97,98,99,40,101,40,103,104,105,48,107,48,109,74,111,74,113,76,115,76,117,118,119,78,121,78,123,88,125,88,127,128,129,130,131,96,133,134,135,136,137,96,139,140,141,100,143,144,145,100,147,148,149,150,151,108,153,154,155,108,157,158,159,160,161,110,163,110,165,166,167,168,169,170,171,112,173,174,175,176,177,112,179,180,181,114,183,114,185,186,187,188,189,116,191,116,193,194,195,196,197,122,199,122,201,202,203,204,205,206,207,124,209,210,211,212,213,214,215,124,217,218,219,220,221,222,223,126,225,226,227,126,229,230,231,142,233,234,235,142,237,164,239,240,241,164,243,244,245,246,247,184,249,250,251,184,253,254,255,256,257,258,259,190,261,262,263,264,265,190,267,268,269,270,271,272,273,274,275,192,277,278,279,192,281,282,283,284,285,200,287,200,289,290,291,276,293,294,295,296,297,276,299,300,301,280,303,304,305,280,307,288,309,288,311,312,313,298,315,316,317,318,319,298,321,302,323,302,325,326,327,322,329,322,331,332,333,324,335,336,337,338,339,340,341,324,343,344,345,346,347,348,349,328,351,352,353,328,355,356,357,330,359,360,361,330,363]
 },{
  "mechanisms": [{
   "indexes": [1,23,59],
@@ -501,7 +501,7 @@
   "indexes": [1,3,5,7,9,10,11,13,14,15,16,17,18,19,21,23,25,26,27,29,31,33,35,37,39,41,42,43,44,45,47,49,50,51,52,53,54,55,56,57,59,61,62,63,65,67,68,69,70,71,73,75,77,79,80,81,83,84,85,87,89,90,91,92,93,95,97,98,99,101,103,104,105,107,109,111,113,115,117,118,119,121,123,125,127,128,129,130,131,133,134,135,136,137,139,140,141,143,144,145,147,148,149,150,151,153,154,155,157,158,159,160,161,163,165,166,167,168,169,170,171,173,174,175,176,177,179,180,181,183,185,186,187,188,189,191,193,194,195,196,197,199,201,202,203,204,205,206,207,209,210,211,212,213,214,215,217,218,219,220,221,222,223,225,226,227,229,230,231,233,234,235,237,239,240,241,243,244,245,246,247,249,250,251,253,254,255,256,257,258,259,261,262,263,264,265,267,268,269,270,271,272,273,274,275,277,278,279,281,282,283,284,285,287,289,290,291,293,294,295,296,297,299,300,301,303,304,305,307,309,311,312,313,315,316,317,318,319,321,323,325,326,327,329,331,332,333,335,336,337,338,339,340,341,343,344,345,346,347,348,349,351,352,353,355,356,357,359,360,361,363],
   "name": "pas"
  }],
- "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,0,13,14,15,16,17,18,19,0,21,2,23,4,25,26,27,4,29,6,31,6,33,8,35,8,37,12,39,12,41,42,43,44,45,22,47,22,49,50,51,52,53,54,55,56,57,24,59,28,61,62,63,28,65,30,67,68,69,70,71,30,73,32,75,32,77,34,79,80,81,34,83,84,85,36,87,36,89,90,91,92,93,38,95,38,97,98,99,40,101,40,103,104,105,48,107,48,109,74,111,74,113,76,115,76,117,118,119,78,121,78,123,88,125,88,127,128,129,130,131,96,133,134,135,136,137,96,139,140,141,100,143,144,145,100,147,148,149,150,151,108,153,154,155,108,157,158,159,160,161,110,163,110,165,166,167,168,169,170,171,112,173,174,175,176,177,112,179,180,181,114,183,114,185,186,187,188,189,116,191,116,193,194,195,196,197,122,199,122,201,202,203,204,205,206,207,124,209,210,211,212,213,214,215,124,217,218,219,220,221,222,223,126,225,226,227,126,229,230,231,142,233,234,235,142,237,164,239,240,241,164,243,244,245,246,247,184,249,250,251,184,253,254,255,256,257,258,259,190,261,262,263,264,265,190,267,268,269,270,271,272,273,274,275,192,277,278,279,192,281,282,283,284,285,200,287,200,289,290,291,276,293,294,295,296,297,276,299,300,301,280,303,304,305,280,307,288,309,288,311,312,313,298,315,316,317,318,319,298,321,302,323,302,325,326,327,322,329,322,331,332,333,324,335,336,337,338,339,340,341,324,343,344,345,346,347,348,349,328,351,352,353,328,355,356,357,330,359,360,361,330,363]
+ "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,0,13,14,15,16,17,18,19,0,21,0,23,4,25,26,27,4,29,6,31,6,33,8,35,8,37,12,39,12,41,42,43,44,45,22,47,22,49,50,51,52,53,54,55,56,57,0,59,28,61,62,63,28,65,30,67,68,69,70,71,30,73,32,75,32,77,34,79,80,81,34,83,84,85,36,87,36,89,90,91,92,93,38,95,38,97,98,99,40,101,40,103,104,105,48,107,48,109,74,111,74,113,76,115,76,117,118,119,78,121,78,123,88,125,88,127,128,129,130,131,96,133,134,135,136,137,96,139,140,141,100,143,144,145,100,147,148,149,150,151,108,153,154,155,108,157,158,159,160,161,110,163,110,165,166,167,168,169,170,171,112,173,174,175,176,177,112,179,180,181,114,183,114,185,186,187,188,189,116,191,116,193,194,195,196,197,122,199,122,201,202,203,204,205,206,207,124,209,210,211,212,213,214,215,124,217,218,219,220,221,222,223,126,225,226,227,126,229,230,231,142,233,234,235,142,237,164,239,240,241,164,243,244,245,246,247,184,249,250,251,184,253,254,255,256,257,258,259,190,261,262,263,264,265,190,267,268,269,270,271,272,273,274,275,192,277,278,279,192,281,282,283,284,285,200,287,200,289,290,291,276,293,294,295,296,297,276,299,300,301,280,303,304,305,280,307,288,309,288,311,312,313,298,315,316,317,318,319,298,321,302,323,302,325,326,327,322,329,322,331,332,333,324,335,336,337,338,339,340,341,324,343,344,345,346,347,348,349,328,351,352,353,328,355,356,357,330,359,360,361,330,363]
 },{
  "mechanisms": [{
   "indexes": [1,19,57],
@@ -564,7 +564,7 @@
   "indexes": [1,3,5,7,9,10,11,12,13,15,17,19,21,22,23,25,27,29,31,33,34,35,37,39,41,42,43,45,47,48,49,50,51,52,53,55,57,59,60,61,63,65,66,67,69,71,73,74,75,77,78,79,81,83,85,86,87,88,89,91,93,95,97,99,100,101,102,103,105,107,109,110,111,113,115,116,117,119,121,123,124,125,127,128,129,131,133,135,137,138,139,141,143,144,145,147,149,151,153,154,155,157,159,161,162,163,165,166,167,169,170,171,173,175,176,177,179,180,181,182,183,185,186,187,189,191,192,193,194,195,197,198,199,201,203,205,207,208,209,211,212,213,215,216,217,219,220,221,223,225,226,227,229,230,231,232,233,235,237,239,241,243,244,245,247,249,251,253,254,255,256,257,259,261,262,263,264,265,267,269,271,273,274,275,277,279,281,283,285,286,287,289,291,292,293,295,297,299,300,301,302,303,305,306,307,308,309,310,311,313,314,315,317,318,319,320,321,322,323,324,325,327,328,329,331,332,333,335,337,338,339,341,343,345,346,347,348,349,351,353,355,357,359,360,361],
   "name": "pas"
  }],
- "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,0,15,0,17,2,19,4,21,22,23,4,25,6,27,6,29,8,31,8,33,34,35,14,37,14,39,16,41,42,43,16,45,18,47,48,49,50,51,52,53,18,55,20,57,24,59,60,61,24,63,26,65,66,67,26,69,28,71,28,73,74,75,30,77,78,79,30,81,32,83,32,85,86,87,88,89,36,91,36,93,46,95,46,97,56,99,100,101,102,103,56,105,64,107,64,109,110,111,68,113,68,115,116,117,70,119,70,121,72,123,124,125,72,127,128,129,76,131,76,133,80,135,80,137,138,139,82,141,82,143,144,145,92,147,92,149,94,151,94,153,154,155,96,157,96,159,104,161,162,163,104,165,166,167,106,169,170,171,106,173,120,175,176,177,120,179,180,181,182,183,122,185,186,187,122,189,126,191,192,193,194,195,126,197,198,199,132,201,132,203,140,205,140,207,208,209,142,211,212,213,142,215,216,217,146,219,220,221,146,223,152,225,226,227,152,229,230,231,232,233,160,235,160,237,172,239,172,241,174,243,244,245,174,247,188,249,188,251,190,253,254,255,256,257,190,259,218,261,262,263,264,265,218,267,224,269,224,271,246,273,274,275,246,277,248,279,248,281,260,283,260,285,286,287,278,289,278,291,292,293,282,295,282,297,288,299,300,301,302,303,288,305,306,307,308,309,310,311,304,313,314,315,304,317,318,319,320,321,322,323,324,325,312,327,328,329,312,331,332,333,334,335,334,337,338,339,340,341,340,343,342,345,346,347,348,349,342,351,344,353,344,355,356,357,356,359,360,361]
+ "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,0,15,0,17,0,19,4,21,22,23,4,25,6,27,6,29,8,31,8,33,34,35,14,37,14,39,16,41,42,43,16,45,18,47,48,49,50,51,52,53,18,55,0,57,24,59,60,61,24,63,26,65,66,67,26,69,28,71,28,73,74,75,30,77,78,79,30,81,32,83,32,85,86,87,88,89,36,91,36,93,46,95,46,97,56,99,100,101,102,103,56,105,64,107,64,109,110,111,68,113,68,115,116,117,70,119,70,121,72,123,124,125,72,127,128,129,76,131,76,133,80,135,80,137,138,139,82,141,82,143,144,145,92,147,92,149,94,151,94,153,154,155,96,157,96,159,104,161,162,163,104,165,166,167,106,169,170,171,106,173,120,175,176,177,120,179,180,181,182,183,122,185,186,187,122,189,126,191,192,193,194,195,126,197,198,199,132,201,132,203,140,205,140,207,208,209,142,211,212,213,142,215,216,217,146,219,220,221,146,223,152,225,226,227,152,229,230,231,232,233,160,235,160,237,172,239,172,241,174,243,244,245,174,247,188,249,188,251,190,253,254,255,256,257,190,259,218,261,262,263,264,265,218,267,224,269,224,271,246,273,274,275,246,277,248,279,248,281,260,283,260,285,286,287,278,289,278,291,292,293,282,295,282,297,288,299,300,301,302,303,288,305,306,307,308,309,310,311,304,313,314,315,304,317,318,319,320,321,322,323,324,325,312,327,328,329,312,331,332,333,334,335,334,337,338,339,340,341,340,343,342,345,346,347,348,349,342,351,344,353,344,355,356,357,356,359,360,361]
 },{
  "mechanisms": [{
   "indexes": [1,19,57],
@@ -627,7 +627,7 @@
   "indexes": [1,3,5,7,9,10,11,12,13,15,17,19,21,22,23,25,27,29,31,33,34,35,37,39,41,42,43,45,47,48,49,50,51,52,53,55,57,59,60,61,63,65,66,67,69,71,73,74,75,77,78,79,81,83,85,86,87,88,89,91,93,95,97,99,100,101,102,103,105,107,109,110,111,113,115,116,117,119,121,123,124,125,127,128,129,131,133,135,137,138,139,141,143,144,145,147,149,151,153,154,155,157,159,161,162,163,165,166,167,169,170,171,173,175,176,177,179,180,181,182,183,185,186,187,189,191,192,193,194,195,197,198,199,201,203,205,207,208,209,211,212,213,215,216,217,219,220,221,223,225,226,227,229,230,231,232,233,235,237,239,241,243,244,245,247,249,251,253,254,255,256,257,259,261,262,263,264,265,267,269,271,273,274,275,277,279,281,283,285,286,287,289,291,292,293,295,297,299,300,301,302,303,305,306,307,308,309,310,311,313,314,315,317,318,319,320,321,322,323,324,325,327,328,329,331,332,333,335,337,338,339,341,343,345,346,347,348,349,351,353,355,357,359,360,361],
   "name": "pas"
  }],
- "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,0,15,0,17,2,19,4,21,22,23,4,25,6,27,6,29,8,31,8,33,34,35,14,37,14,39,16,41,42,43,16,45,18,47,48,49,50,51,52,53,18,55,20,57,24,59,60,61,24,63,26,65,66,67,26,69,28,71,28,73,74,75,30,77,78,79,30,81,32,83,32,85,86,87,88,89,36,91,36,93,46,95,46,97,56,99,100,101,102,103,56,105,64,107,64,109,110,111,68,113,68,115,116,117,70,119,70,121,72,123,124,125,72,127,128,129,76,131,76,133,80,135,80,137,138,139,82,141,82,143,144,145,92,147,92,149,94,151,94,153,154,155,96,157,96,159,104,161,162,163,104,165,166,167,106,169,170,171,106,173,120,175,176,177,120,179,180,181,182,183,122,185,186,187,122,189,126,191,192,193,194,195,126,197,198,199,132,201,132,203,140,205,140,207,208,209,142,211,212,213,142,215,216,217,146,219,220,221,146,223,152,225,226,227,152,229,230,231,232,233,160,235,160,237,172,239,172,241,174,243,244,245,174,247,188,249,188,251,190,253,254,255,256,257,190,259,218,261,262,263,264,265,218,267,224,269,224,271,246,273,274,275,246,277,248,279,248,281,260,283,260,285,286,287,278,289,278,291,292,293,282,295,282,297,288,299,300,301,302,303,288,305,306,307,308,309,310,311,304,313,314,315,304,317,318,319,320,321,322,323,324,325,312,327,328,329,312,331,332,333,334,335,334,337,338,339,340,341,340,343,342,345,346,347,348,349,342,351,344,353,344,355,356,357,356,359,360,361]
+ "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,0,15,0,17,0,19,4,21,22,23,4,25,6,27,6,29,8,31,8,33,34,35,14,37,14,39,16,41,42,43,16,45,18,47,48,49,50,51,52,53,18,55,0,57,24,59,60,61,24,63,26,65,66,67,26,69,28,71,28,73,74,75,30,77,78,79,30,81,32,83,32,85,86,87,88,89,36,91,36,93,46,95,46,97,56,99,100,101,102,103,56,105,64,107,64,109,110,111,68,113,68,115,116,117,70,119,70,121,72,123,124,125,72,127,128,129,76,131,76,133,80,135,80,137,138,139,82,141,82,143,144,145,92,147,92,149,94,151,94,153,154,155,96,157,96,159,104,161,162,163,104,165,166,167,106,169,170,171,106,173,120,175,176,177,120,179,180,181,182,183,122,185,186,187,122,189,126,191,192,193,194,195,126,197,198,199,132,201,132,203,140,205,140,207,208,209,142,211,212,213,142,215,216,217,146,219,220,221,146,223,152,225,226,227,152,229,230,231,232,233,160,235,160,237,172,239,172,241,174,243,244,245,174,247,188,249,188,251,190,253,254,255,256,257,190,259,218,261,262,263,264,265,218,267,224,269,224,271,246,273,274,275,246,277,248,279,248,281,260,283,260,285,286,287,278,289,278,291,292,293,282,295,282,297,288,299,300,301,302,303,288,305,306,307,308,309,310,311,304,313,314,315,304,317,318,319,320,321,322,323,324,325,312,327,328,329,312,331,332,333,334,335,334,337,338,339,340,341,340,343,342,345,346,347,348,349,342,351,344,353,344,355,356,357,356,359,360,361]
 },{
  "mechanisms": [{
   "indexes": [1,19,57],
@@ -690,7 +690,7 @@
   "indexes": [1,3,5,7,9,10,11,12,13,15,17,19,21,22,23,25,27,29,31,33,34,35,37,39,41,42,43,45,47,48,49,50,51,52,53,55,57,59,60,61,63,65,66,67,69,71,73,74,75,77,78,79,81,83,85,86,87,88,89,91,93,95,97,99,100,101,102,103,105,107,109,110,111,113,115,116,117,119,121,123,124,125,127,128,129,131,133,135,137,138,139,141,143,144,145,147,149,151,153,154,155,157,159,161,162,163,165,166,167,169,170,171,173,175,176,177,179,180,181,182,183,185,186,187,189,191,192,193,194,195,197,198,199,201,203,205,207,208,209,211,212,213,215,216,217,219,220,221,223,225,226,227,229,230,231,232,233,235,237,239,241,243,244,245,247,249,251,253,254,255,256,257,259,261,262,263,264,265,267,269,271,273,274,275,277,279,281,283,285,286,287,289,291,292,293,295,297,299,300,301,302,303,305,306,307,308,309,310,311,313,314,315,317,318,319,320,321,322,323,324,325,327,328,329,331,332,333,335,337,338,339,341,343,345,346,347,348,349,351,353,355,357,359,360,361],
   "name": "pas"
  }],
- "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,0,15,0,17,2,19,4,21,22,23,4,25,6,27,6,29,8,31,8,33,34,35,14,37,14,39,16,41,42,43,16,45,18,47,48,49,50,51,52,53,18,55,20,57,24,59,60,61,24,63,26,65,66,67,26,69,28,71,28,73,74,75,30,77,78,79,30,81,32,83,32,85,86,87,88,89,36,91,36,93,46,95,46,97,56,99,100,101,102,103,56,105,64,107,64,109,110,111,68,113,68,115,116,117,70,119,70,121,72,123,124,125,72,127,128,129,76,131,76,133,80,135,80,137,138,139,82,141,82,143,144,145,92,147,92,149,94,151,94,153,154,155,96,157,96,159,104,161,162,163,104,165,166,167,106,169,170,171,106,173,120,175,176,177,120,179,180,181,182,183,122,185,186,187,122,189,126,191,192,193,194,195,126,197,198,199,132,201,132,203,140,205,140,207,208,209,142,211,212,213,142,215,216,217,146,219,220,221,146,223,152,225,226,227,152,229,230,231,232,233,160,235,160,237,172,239,172,241,174,243,244,245,174,247,188,249,188,251,190,253,254,255,256,257,190,259,218,261,262,263,264,265,218,267,224,269,224,271,246,273,274,275,246,277,248,279,248,281,260,283,260,285,286,287,278,289,278,291,292,293,282,295,282,297,288,299,300,301,302,303,288,305,306,307,308,309,310,311,304,313,314,315,304,317,318,319,320,321,322,323,324,325,312,327,328,329,312,331,332,333,334,335,334,337,338,339,340,341,340,343,342,345,346,347,348,349,342,351,344,353,344,355,356,357,356,359,360,361]
+ "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,0,15,0,17,0,19,4,21,22,23,4,25,6,27,6,29,8,31,8,33,34,35,14,37,14,39,16,41,42,43,16,45,18,47,48,49,50,51,52,53,18,55,0,57,24,59,60,61,24,63,26,65,66,67,26,69,28,71,28,73,74,75,30,77,78,79,30,81,32,83,32,85,86,87,88,89,36,91,36,93,46,95,46,97,56,99,100,101,102,103,56,105,64,107,64,109,110,111,68,113,68,115,116,117,70,119,70,121,72,123,124,125,72,127,128,129,76,131,76,133,80,135,80,137,138,139,82,141,82,143,144,145,92,147,92,149,94,151,94,153,154,155,96,157,96,159,104,161,162,163,104,165,166,167,106,169,170,171,106,173,120,175,176,177,120,179,180,181,182,183,122,185,186,187,122,189,126,191,192,193,194,195,126,197,198,199,132,201,132,203,140,205,140,207,208,209,142,211,212,213,142,215,216,217,146,219,220,221,146,223,152,225,226,227,152,229,230,231,232,233,160,235,160,237,172,239,172,241,174,243,244,245,174,247,188,249,188,251,190,253,254,255,256,257,190,259,218,261,262,263,264,265,218,267,224,269,224,271,246,273,274,275,246,277,248,279,248,281,260,283,260,285,286,287,278,289,278,291,292,293,282,295,282,297,288,299,300,301,302,303,288,305,306,307,308,309,310,311,304,313,314,315,304,317,318,319,320,321,322,323,324,325,312,327,328,329,312,331,332,333,334,335,334,337,338,339,340,341,340,343,342,345,346,347,348,349,342,351,344,353,344,355,356,357,356,359,360,361]
 },{
  "mechanisms": [{
   "indexes": [1,19,57],
@@ -753,7 +753,7 @@
   "indexes": [1,3,5,7,9,10,11,12,13,15,17,19,21,22,23,25,27,29,31,33,34,35,37,39,41,42,43,45,47,48,49,50,51,52,53,55,57,59,60,61,63,65,66,67,69,71,73,74,75,77,78,79,81,83,85,86,87,88,89,91,93,95,97,99,100,101,102,103,105,107,109,110,111,113,115,116,117,119,121,123,124,125,127,128,129,131,133,135,137,138,139,141,143,144,145,147,149,151,153,154,155,157,159,161,162,163,165,166,167,169,170,171,173,175,176,177,179,180,181,182,183,185,186,187,189,191,192,193,194,195,197,198,199,201,203,205,207,208,209,211,212,213,215,216,217,219,220,221,223,225,226,227,229,230,231,232,233,235,237,239,241,243,244,245,247,249,251,253,254,255,256,257,259,261,262,263,264,265,267,269,271,273,274,275,277,279,281,283,285,286,287,289,291,292,293,295,297,299,300,301,302,303,305,306,307,308,309,310,311,313,314,315,317,318,319,320,321,322,323,324,325,327,328,329,331,332,333,335,337,338,339,341,343,345,346,347,348,349,351,353,355,357,359,360,361],
   "name": "pas"
  }],
- "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,0,15,0,17,2,19,4,21,22,23,4,25,6,27,6,29,8,31,8,33,34,35,14,37,14,39,16,41,42,43,16,45,18,47,48,49,50,51,52,53,18,55,20,57,24,59,60,61,24,63,26,65,66,67,26,69,28,71,28,73,74,75,30,77,78,79,30,81,32,83,32,85,86,87,88,89,36,91,36,93,46,95,46,97,56,99,100,101,102,103,56,105,64,107,64,109,110,111,68,113,68,115,116,117,70,119,70,121,72,123,124,125,72,127,128,129,76,131,76,133,80,135,80,137,138,139,82,141,82,143,144,145,92,147,92,149,94,151,94,153,154,155,96,157,96,159,104,161,162,163,104,165,166,167,106,169,170,171,106,173,120,175,176,177,120,179,180,181,182,183,122,185,186,187,122,189,126,191,192,193,194,195,126,197,198,199,132,201,132,203,140,205,140,207,208,209,142,211,212,213,142,215,216,217,146,219,220,221,146,223,152,225,226,227,152,229,230,231,232,233,160,235,160,237,172,239,172,241,174,243,244,245,174,247,188,249,188,251,190,253,254,255,256,257,190,259,218,261,262,263,264,265,218,267,224,269,224,271,246,273,274,275,246,277,248,279,248,281,260,283,260,285,286,287,278,289,278,291,292,293,282,295,282,297,288,299,300,301,302,303,288,305,306,307,308,309,310,311,304,313,314,315,304,317,318,319,320,321,322,323,324,325,312,327,328,329,312,331,332,333,334,335,334,337,338,339,340,341,340,343,342,345,346,347,348,349,342,351,344,353,344,355,356,357,356,359,360,361]
+ "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,0,15,0,17,0,19,4,21,22,23,4,25,6,27,6,29,8,31,8,33,34,35,14,37,14,39,16,41,42,43,16,45,18,47,48,49,50,51,52,53,18,55,0,57,24,59,60,61,24,63,26,65,66,67,26,69,28,71,28,73,74,75,30,77,78,79,30,81,32,83,32,85,86,87,88,89,36,91,36,93,46,95,46,97,56,99,100,101,102,103,56,105,64,107,64,109,110,111,68,113,68,115,116,117,70,119,70,121,72,123,124,125,72,127,128,129,76,131,76,133,80,135,80,137,138,139,82,141,82,143,144,145,92,147,92,149,94,151,94,153,154,155,96,157,96,159,104,161,162,163,104,165,166,167,106,169,170,171,106,173,120,175,176,177,120,179,180,181,182,183,122,185,186,187,122,189,126,191,192,193,194,195,126,197,198,199,132,201,132,203,140,205,140,207,208,209,142,211,212,213,142,215,216,217,146,219,220,221,146,223,152,225,226,227,152,229,230,231,232,233,160,235,160,237,172,239,172,241,174,243,244,245,174,247,188,249,188,251,190,253,254,255,256,257,190,259,218,261,262,263,264,265,218,267,224,269,224,271,246,273,274,275,246,277,248,279,248,281,260,283,260,285,286,287,278,289,278,291,292,293,282,295,282,297,288,299,300,301,302,303,288,305,306,307,308,309,310,311,304,313,314,315,304,317,318,319,320,321,322,323,324,325,312,327,328,329,312,331,332,333,334,335,334,337,338,339,340,341,340,343,342,345,346,347,348,349,342,351,344,353,344,355,356,357,356,359,360,361]
 },{
  "mechanisms": [{
   "indexes": [1,27,67],
@@ -816,7 +816,7 @@
   "indexes": [1,3,5,7,9,10,11,12,13,14,15,17,19,20,21,22,23,24,25,27,29,31,33,34,35,36,37,38,39,41,43,44,45,46,47,49,50,51,52,53,55,56,57,58,59,60,61,62,63,65,67,69,71,73,74,75,76,77,78,79,81,82,83,84,85,87,88,89,90,91,93,95,96,97,98,99,100,101,103,104,105,106,107,108,109,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,143,144,145,147,149,150,151,152,153,154,155,157,159,160,161,162,163,165,166,167,168,169,170,171,172,173,175,176,177,178,179,180,181,183,185,187,188,189,190,191,193,194,195],
   "name": "pas"
  }],
- "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,14,15,0,17,0,19,20,21,22,23,24,25,2,27,4,29,4,31,6,33,34,35,36,37,38,39,6,41,8,43,44,45,46,47,8,49,50,51,52,53,18,55,56,57,58,59,60,61,62,63,18,65,28,67,30,69,30,71,32,73,74,75,76,77,78,79,32,81,82,83,84,85,42,87,88,89,90,91,42,93,66,95,96,97,98,99,100,101,66,103,104,105,106,107,108,109,70,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,70,143,144,145,72,147,72,149,150,151,152,153,154,155,80,157,80,159,160,161,162,163,142,165,166,167,168,169,170,171,172,173,142,175,176,177,178,179,180,181,146,183,146,185,148,187,188,189,190,191,148,193,194,195]
+ "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,14,15,0,17,0,19,20,21,22,23,24,25,0,27,4,29,4,31,6,33,34,35,36,37,38,39,6,41,8,43,44,45,46,47,8,49,50,51,52,53,18,55,56,57,58,59,60,61,62,63,18,65,0,67,30,69,30,71,32,73,74,75,76,77,78,79,32,81,82,83,84,85,42,87,88,89,90,91,42,93,66,95,96,97,98,99,100,101,66,103,104,105,106,107,108,109,70,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,70,143,144,145,72,147,72,149,150,151,152,153,154,155,80,157,80,159,160,161,162,163,142,165,166,167,168,169,170,171,172,173,142,175,176,177,178,179,180,181,146,183,146,185,148,187,188,189,190,191,148,193,194,195]
 },{
  "mechanisms": [{
   "indexes": [1,27,67],
@@ -879,7 +879,7 @@
   "indexes": [1,3,5,7,9,10,11,12,13,14,15,17,19,20,21,22,23,24,25,27,29,31,33,34,35,36,37,38,39,41,43,44,45,46,47,49,50,51,52,53,55,56,57,58,59,60,61,62,63,65,67,69,71,73,74,75,76,77,78,79,81,82,83,84,85,87,88,89,90,91,93,95,96,97,98,99,100,101,103,104,105,106,107,108,109,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,143,144,145,147,149,150,151,152,153,154,155,157,159,160,161,162,163,165,166,167,168,169,170,171,172,173,175,176,177,178,179,180,181,183,185,187,188,189,190,191,193,194,195],
   "name": "pas"
  }],
- "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,14,15,0,17,0,19,20,21,22,23,24,25,2,27,4,29,4,31,6,33,34,35,36,37,38,39,6,41,8,43,44,45,46,47,8,49,50,51,52,53,18,55,56,57,58,59,60,61,62,63,18,65,28,67,30,69,30,71,32,73,74,75,76,77,78,79,32,81,82,83,84,85,42,87,88,89,90,91,42,93,66,95,96,97,98,99,100,101,66,103,104,105,106,107,108,109,70,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,70,143,144,145,72,147,72,149,150,151,152,153,154,155,80,157,80,159,160,161,162,163,142,165,166,167,168,169,170,171,172,173,142,175,176,177,178,179,180,181,146,183,146,185,148,187,188,189,190,191,148,193,194,195]
+ "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,14,15,0,17,0,19,20,21,22,23,24,25,0,27,4,29,4,31,6,33,34,35,36,37,38,39,6,41,8,43,44,45,46,47,8,49,50,51,52,53,18,55,56,57,58,59,60,61,62,63,18,65,0,67,30,69,30,71,32,73,74,75,76,77,78,79,32,81,82,83,84,85,42,87,88,89,90,91,42,93,66,95,96,97,98,99,100,101,66,103,104,105,106,107,108,109,70,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,70,143,144,145,72,147,72,149,150,151,152,153,154,155,80,157,80,159,160,161,162,163,142,165,166,167,168,169,170,171,172,173,142,175,176,177,178,179,180,181,146,183,146,185,148,187,188,189,190,191,148,193,194,195]
 },{
  "mechanisms": [{
   "indexes": [1,27,67],
@@ -942,7 +942,7 @@
   "indexes": [1,3,5,7,9,10,11,12,13,14,15,17,19,20,21,22,23,24,25,27,29,31,33,34,35,36,37,38,39,41,43,44,45,46,47,49,50,51,52,53,55,56,57,58,59,60,61,62,63,65,67,69,71,73,74,75,76,77,78,79,81,82,83,84,85,87,88,89,90,91,93,95,96,97,98,99,100,101,103,104,105,106,107,108,109,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,143,144,145,147,149,150,151,152,153,154,155,157,159,160,161,162,163,165,166,167,168,169,170,171,172,173,175,176,177,178,179,180,181,183,185,187,188,189,190,191,193,194,195],
   "name": "pas"
  }],
- "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,14,15,0,17,0,19,20,21,22,23,24,25,2,27,4,29,4,31,6,33,34,35,36,37,38,39,6,41,8,43,44,45,46,47,8,49,50,51,52,53,18,55,56,57,58,59,60,61,62,63,18,65,28,67,30,69,30,71,32,73,74,75,76,77,78,79,32,81,82,83,84,85,42,87,88,89,90,91,42,93,66,95,96,97,98,99,100,101,66,103,104,105,106,107,108,109,70,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,70,143,144,145,72,147,72,149,150,151,152,153,154,155,80,157,80,159,160,161,162,163,142,165,166,167,168,169,170,171,172,173,142,175,176,177,178,179,180,181,146,183,146,185,148,187,188,189,190,191,148,193,194,195]
+ "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,14,15,0,17,0,19,20,21,22,23,24,25,0,27,4,29,4,31,6,33,34,35,36,37,38,39,6,41,8,43,44,45,46,47,8,49,50,51,52,53,18,55,56,57,58,59,60,61,62,63,18,65,0,67,30,69,30,71,32,73,74,75,76,77,78,79,32,81,82,83,84,85,42,87,88,89,90,91,42,93,66,95,96,97,98,99,100,101,66,103,104,105,106,107,108,109,70,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,70,143,144,145,72,147,72,149,150,151,152,153,154,155,80,157,80,159,160,161,162,163,142,165,166,167,168,169,170,171,172,173,142,175,176,177,178,179,180,181,146,183,146,185,148,187,188,189,190,191,148,193,194,195]
 },{
  "mechanisms": [{
   "indexes": [1,27,67],
@@ -1005,7 +1005,7 @@
   "indexes": [1,3,5,7,9,10,11,12,13,14,15,17,19,20,21,22,23,24,25,27,29,31,33,34,35,36,37,38,39,41,43,44,45,46,47,49,50,51,52,53,55,56,57,58,59,60,61,62,63,65,67,69,71,73,74,75,76,77,78,79,81,82,83,84,85,87,88,89,90,91,93,95,96,97,98,99,100,101,103,104,105,106,107,108,109,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,143,144,145,147,149,150,151,152,153,154,155,157,159,160,161,162,163,165,166,167,168,169,170,171,172,173,175,176,177,178,179,180,181,183,185,187,188,189,190,191,193,194,195],
   "name": "pas"
  }],
- "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,14,15,0,17,0,19,20,21,22,23,24,25,2,27,4,29,4,31,6,33,34,35,36,37,38,39,6,41,8,43,44,45,46,47,8,49,50,51,52,53,18,55,56,57,58,59,60,61,62,63,18,65,28,67,30,69,30,71,32,73,74,75,76,77,78,79,32,81,82,83,84,85,42,87,88,89,90,91,42,93,66,95,96,97,98,99,100,101,66,103,104,105,106,107,108,109,70,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,70,143,144,145,72,147,72,149,150,151,152,153,154,155,80,157,80,159,160,161,162,163,142,165,166,167,168,169,170,171,172,173,142,175,176,177,178,179,180,181,146,183,146,185,148,187,188,189,190,191,148,193,194,195]
+ "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,14,15,0,17,0,19,20,21,22,23,24,25,0,27,4,29,4,31,6,33,34,35,36,37,38,39,6,41,8,43,44,45,46,47,8,49,50,51,52,53,18,55,56,57,58,59,60,61,62,63,18,65,0,67,30,69,30,71,32,73,74,75,76,77,78,79,32,81,82,83,84,85,42,87,88,89,90,91,42,93,66,95,96,97,98,99,100,101,66,103,104,105,106,107,108,109,70,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,70,143,144,145,72,147,72,149,150,151,152,153,154,155,80,157,80,159,160,161,162,163,142,165,166,167,168,169,170,171,172,173,142,175,176,177,178,179,180,181,146,183,146,185,148,187,188,189,190,191,148,193,194,195]
 },{
  "mechanisms": [{
   "indexes": [1,19,57],
@@ -1068,7 +1068,7 @@
   "indexes": [1,3,5,7,9,11,12,13,14,15,17,19,21,23,25,26,27,28,29,31,32,33,34,35,37,39,40,41,43,45,46,47,48,49,50,51,53,55,57,59,61,63,64,65,66,67,69,70,71,73,75,77,79,81,83,84,85,87,89,91,92,93,94,95,97,98,99,100,101,103,105,107,108,109,110,111,113,114,115,116,117,119,120,121,122,123,125,126,127,128,129,131,133,134,135,137,138,139,140,141,142,143,145,147,148,149,150,151,153,154,155,157,159,160,161,163,164,165,166,167,168,169,170,171,173,174,175,177,178,179,180,181,183,184,185,186,187,189,190,191,193,194,195,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,217,218,219,221,222,223,225,226,227,228,229,231,233,234,235,237,238,239,241,243,245,247,249],
   "name": "pas"
  }],
- "parent_index": [0,0,1,0,3,0,5,0,7,0,9,0,11,12,13,14,15,0,17,2,19,4,21,4,23,6,25,26,27,28,29,6,31,32,33,34,35,8,37,8,39,40,41,10,43,10,45,46,47,48,49,50,51,18,53,18,55,20,57,22,59,22,61,24,63,64,65,66,67,24,69,70,71,30,73,30,75,36,77,36,79,38,81,38,83,84,85,42,87,42,89,44,91,92,93,94,95,44,97,98,99,100,101,52,103,52,105,54,107,108,109,110,111,54,113,114,115,116,117,56,119,120,121,122,123,56,125,126,127,128,129,60,131,60,133,134,135,62,137,138,139,140,141,142,143,62,145,82,147,148,149,150,151,82,153,154,155,90,157,90,159,160,161,132,163,164,165,166,167,168,169,170,171,132,173,174,175,136,177,178,179,180,181,136,183,184,185,186,187,146,189,190,191,146,193,194,195,172,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,172,217,218,219,176,221,222,223,176,225,226,227,228,229,216,231,216,233,234,235,220,237,238,239,220,241,232,243,232,245,236,247,236,249]
+ "parent_index": [0,0,1,0,3,0,5,0,7,0,9,0,11,12,13,14,15,0,17,0,19,4,21,4,23,6,25,26,27,28,29,6,31,32,33,34,35,8,37,8,39,40,41,10,43,10,45,46,47,48,49,50,51,18,53,18,55,0,57,22,59,22,61,24,63,64,65,66,67,24,69,70,71,30,73,30,75,36,77,36,79,38,81,38,83,84,85,42,87,42,89,44,91,92,93,94,95,44,97,98,99,100,101,52,103,52,105,54,107,108,109,110,111,54,113,114,115,116,117,56,119,120,121,122,123,56,125,126,127,128,129,60,131,60,133,134,135,62,137,138,139,140,141,142,143,62,145,82,147,148,149,150,151,82,153,154,155,90,157,90,159,160,161,132,163,164,165,166,167,168,169,170,171,132,173,174,175,136,177,178,179,180,181,136,183,184,185,186,187,146,189,190,191,146,193,194,195,172,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,172,217,218,219,176,221,222,223,176,225,226,227,228,229,216,231,216,233,234,235,220,237,238,239,220,241,232,243,232,245,236,247,236,249]
 },{
  "mechanisms": [{
   "indexes": [1,19,57],
@@ -1131,7 +1131,7 @@
   "indexes": [1,3,5,7,9,11,12,13,14,15,17,19,21,23,25,26,27,28,29,31,32,33,34,35,37,39,40,41,43,45,46,47,48,49,50,51,53,55,57,59,61,63,64,65,66,67,69,70,71,73,75,77,79,81,83,84,85,87,89,91,92,93,94,95,97,98,99,100,101,103,105,107,108,109,110,111,113,114,115,116,117,119,120,121,122,123,125,126,127,128,129,131,133,134,135,137,138,139,140,141,142,143,145,147,148,149,150,151,153,154,155,157,159,160,161,163,164,165,166,167,168,169,170,171,173,174,175,177,178,179,180,181,183,184,185,186,187,189,190,191,193,194,195,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,217,218,219,221,222,223,225,226,227,228,229,231,233,234,235,237,238,239,241,243,245,247,249],
   "name": "pas"
  }],
- "parent_index": [0,0,1,0,3,0,5,0,7,0,9,0,11,12,13,14,15,0,17,2,19,4,21,4,23,6,25,26,27,28,29,6,31,32,33,34,35,8,37,8,39,40,41,10,43,10,45,46,47,48,49,50,51,18,53,18,55,20,57,22,59,22,61,24,63,64,65,66,67,24,69,70,71,30,73,30,75,36,77,36,79,38,81,38,83,84,85,42,87,42,89,44,91,92,93,94,95,44,97,98,99,100,101,52,103,52,105,54,107,108,109,110,111,54,113,114,115,116,117,56,119,120,121,122,123,56,125,126,127,128,129,60,131,60,133,134,135,62,137,138,139,140,141,142,143,62,145,82,147,148,149,150,151,82,153,154,155,90,157,90,159,160,161,132,163,164,165,166,167,168,169,170,171,132,173,174,175,136,177,178,179,180,181,136,183,184,185,186,187,146,189,190,191,146,193,194,195,172,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,172,217,218,219,176,221,222,223,176,225,226,227,228,229,216,231,216,233,234,235,220,237,238,239,220,241,232,243,232,245,236,247,236,249]
+ "parent_index": [0,0,1,0,3,0,5,0,7,0,9,0,11,12,13,14,15,0,17,0,19,4,21,4,23,6,25,26,27,28,29,6,31,32,33,34,35,8,37,8,39,40,41,10,43,10,45,46,47,48,49,50,51,18,53,18,55,0,57,22,59,22,61,24,63,64,65,66,67,24,69,70,71,30,73,30,75,36,77,36,79,38,81,38,83,84,85,42,87,42,89,44,91,92,93,94,95,44,97,98,99,100,101,52,103,52,105,54,107,108,109,110,111,54,113,114,115,116,117,56,119,120,121,122,123,56,125,126,127,128,129,60,131,60,133,134,135,62,137,138,139,140,141,142,143,62,145,82,147,148,149,150,151,82,153,154,155,90,157,90,159,160,161,132,163,164,165,166,167,168,169,170,171,132,173,174,175,136,177,178,179,180,181,136,183,184,185,186,187,146,189,190,191,146,193,194,195,172,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,172,217,218,219,176,221,222,223,176,225,226,227,228,229,216,231,216,233,234,235,220,237,238,239,220,241,232,243,232,245,236,247,236,249]
 },{
  "mechanisms": [{
   "indexes": [1,19,57],
@@ -1194,7 +1194,7 @@
   "indexes": [1,3,5,7,9,11,12,13,14,15,17,19,21,23,25,26,27,28,29,31,32,33,34,35,37,39,40,41,43,45,46,47,48,49,50,51,53,55,57,59,61,63,64,65,66,67,69,70,71,73,75,77,79,81,83,84,85,87,89,91,92,93,94,95,97,98,99,100,101,103,105,107,108,109,110,111,113,114,115,116,117,119,120,121,122,123,125,126,127,128,129,131,133,134,135,137,138,139,140,141,142,143,145,147,148,149,150,151,153,154,155,157,159,160,161,163,164,165,166,167,168,169,170,171,173,174,175,177,178,179,180,181,183,184,185,186,187,189,190,191,193,194,195,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,217,218,219,221,222,223,225,226,227,228,229,231,233,234,235,237,238,239,241,243,245,247,249],
   "name": "pas"
  }],
- "parent_index": [0,0,1,0,3,0,5,0,7,0,9,0,11,12,13,14,15,0,17,2,19,4,21,4,23,6,25,26,27,28,29,6,31,32,33,34,35,8,37,8,39,40,41,10,43,10,45,46,47,48,49,50,51,18,53,18,55,20,57,22,59,22,61,24,63,64,65,66,67,24,69,70,71,30,73,30,75,36,77,36,79,38,81,38,83,84,85,42,87,42,89,44,91,92,93,94,95,44,97,98,99,100,101,52,103,52,105,54,107,108,109,110,111,54,113,114,115,116,117,56,119,120,121,122,123,56,125,126,127,128,129,60,131,60,133,134,135,62,137,138,139,140,141,142,143,62,145,82,147,148,149,150,151,82,153,154,155,90,157,90,159,160,161,132,163,164,165,166,167,168,169,170,171,132,173,174,175,136,177,178,179,180,181,136,183,184,185,186,187,146,189,190,191,146,193,194,195,172,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,172,217,218,219,176,221,222,223,176,225,226,227,228,229,216,231,216,233,234,235,220,237,238,239,220,241,232,243,232,245,236,247,236,249]
+ "parent_index": [0,0,1,0,3,0,5,0,7,0,9,0,11,12,13,14,15,0,17,0,19,4,21,4,23,6,25,26,27,28,29,6,31,32,33,34,35,8,37,8,39,40,41,10,43,10,45,46,47,48,49,50,51,18,53,18,55,0,57,22,59,22,61,24,63,64,65,66,67,24,69,70,71,30,73,30,75,36,77,36,79,38,81,38,83,84,85,42,87,42,89,44,91,92,93,94,95,44,97,98,99,100,101,52,103,52,105,54,107,108,109,110,111,54,113,114,115,116,117,56,119,120,121,122,123,56,125,126,127,128,129,60,131,60,133,134,135,62,137,138,139,140,141,142,143,62,145,82,147,148,149,150,151,82,153,154,155,90,157,90,159,160,161,132,163,164,165,166,167,168,169,170,171,132,173,174,175,136,177,178,179,180,181,136,183,184,185,186,187,146,189,190,191,146,193,194,195,172,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,172,217,218,219,176,221,222,223,176,225,226,227,228,229,216,231,216,233,234,235,220,237,238,239,220,241,232,243,232,245,236,247,236,249]
 },{
  "mechanisms": [{
   "indexes": [1,19,57],
@@ -1257,5 +1257,5 @@
   "indexes": [1,3,5,7,9,11,12,13,14,15,17,19,21,23,25,26,27,28,29,31,32,33,34,35,37,39,40,41,43,45,46,47,48,49,50,51,53,55,57,59,61,63,64,65,66,67,69,70,71,73,75,77,79,81,83,84,85,87,89,91,92,93,94,95,97,98,99,100,101,103,105,107,108,109,110,111,113,114,115,116,117,119,120,121,122,123,125,126,127,128,129,131,133,134,135,137,138,139,140,141,142,143,145,147,148,149,150,151,153,154,155,157,159,160,161,163,164,165,166,167,168,169,170,171,173,174,175,177,178,179,180,181,183,184,185,186,187,189,190,191,193,194,195,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,217,218,219,221,222,223,225,226,227,228,229,231,233,234,235,237,238,239,241,243,245,247,249],
   "name": "pas"
  }],
- "parent_index": [0,0,1,0,3,0,5,0,7,0,9,0,11,12,13,14,15,0,17,2,19,4,21,4,23,6,25,26,27,28,29,6,31,32,33,34,35,8,37,8,39,40,41,10,43,10,45,46,47,48,49,50,51,18,53,18,55,20,57,22,59,22,61,24,63,64,65,66,67,24,69,70,71,30,73,30,75,36,77,36,79,38,81,38,83,84,85,42,87,42,89,44,91,92,93,94,95,44,97,98,99,100,101,52,103,52,105,54,107,108,109,110,111,54,113,114,115,116,117,56,119,120,121,122,123,56,125,126,127,128,129,60,131,60,133,134,135,62,137,138,139,140,141,142,143,62,145,82,147,148,149,150,151,82,153,154,155,90,157,90,159,160,161,132,163,164,165,166,167,168,169,170,171,132,173,174,175,136,177,178,179,180,181,136,183,184,185,186,187,146,189,190,191,146,193,194,195,172,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,172,217,218,219,176,221,222,223,176,225,226,227,228,229,216,231,216,233,234,235,220,237,238,239,220,241,232,243,232,245,236,247,236,249]
+ "parent_index": [0,0,1,0,3,0,5,0,7,0,9,0,11,12,13,14,15,0,17,0,19,4,21,4,23,6,25,26,27,28,29,6,31,32,33,34,35,8,37,8,39,40,41,10,43,10,45,46,47,48,49,50,51,18,53,18,55,0,57,22,59,22,61,24,63,64,65,66,67,24,69,70,71,30,73,30,75,36,77,36,79,38,81,38,83,84,85,42,87,42,89,44,91,92,93,94,95,44,97,98,99,100,101,52,103,52,105,54,107,108,109,110,111,54,113,114,115,116,117,56,119,120,121,122,123,56,125,126,127,128,129,60,131,60,133,134,135,62,137,138,139,140,141,142,143,62,145,82,147,148,149,150,151,82,153,154,155,90,157,90,159,160,161,132,163,164,165,166,167,168,169,170,171,132,173,174,175,136,177,178,179,180,181,136,183,184,185,186,187,146,189,190,191,146,193,194,195,172,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,172,217,218,219,176,221,222,223,176,225,226,227,228,229,216,231,216,233,234,235,220,237,238,239,220,241,232,243,232,245,236,247,236,249]
 }]
diff --git a/miniapp/io.cpp b/miniapp/io.cpp
index 6664cf47e4ddbf1fcd33cd4589553a29cb967255..ac7573ccec32a4036f49c515b80047ccb602a1e0 100644
--- a/miniapp/io.cpp
+++ b/miniapp/io.cpp
@@ -1,13 +1,37 @@
-#include <fstream>
 #include <exception>
+#include <fstream>
+#include <istream>
 
 #include <tclap/CmdLine.h>
 #include <json/src/json.hpp>
 
+#include <util/optional.hpp>
+
 #include "io.hpp"
 
+// Let TCLAP understand value arguments that are of an optional type.
+
+template <typename V>
+struct TCLAP::ArgTraits<nest::mc::util::optional<V>> {
+    using ValueCategory = ValueLike;
+};
+
 namespace nest {
 namespace mc {
+
+// Using static here because we do not want external linkage for this operator
+
+namespace util {
+    template <typename V>
+    static std::istream& operator>>(std::istream& I, optional<V>& v) {
+        V u;
+        if (I >> u) {
+            v = u;
+        }
+        return I;
+    }
+}
+
 namespace io {
 
 /// read simulation options from json file with name fname
@@ -17,7 +41,8 @@ namespace io {
 cl_options read_options(int argc, char** argv) {
 
     // set default options
-    const cl_options defopts{"", 1000, 500, "expsyn", 100, 100., 0.025, false};
+    const cl_options defopts{"", 1000, 500, "expsyn", 100, 100., 0.025, false,
+                             false, 1.0, "trace_", util::nothing};
 
     cl_options options;
     // parse command line arguments
@@ -47,6 +72,17 @@ cl_options read_options(int argc, char** argv) {
             false, defopts.dt, "positive real number", cmd);
         TCLAP::SwitchArg all_to_all_arg(
             "m","alltoall","all to all network", cmd, false);
+        TCLAP::ValueArg<double> probe_ratio_arg(
+            "p", "probe-ratio", "proportion of cells to probe",
+            false, defopts.probe_ratio, "real number in [0,1]", cmd);
+        TCLAP::SwitchArg probe_soma_only_arg(
+            "X", "probe-soma-only", "only probe cell somas, not dendrites", cmd, false);
+        TCLAP::ValueArg<std::string> trace_prefix_arg(
+            "P", "trace-prefix", "write traces to files with this prefix",
+            false, defopts.trace_prefix, "stringr", cmd);
+        TCLAP::ValueArg<util::optional<unsigned>> trace_max_gid_arg(
+            "T", "trace-max-gid", "only trace probes on cells up to this gid",
+            false, defopts.trace_max_gid, "unisgned integer", cmd);
 
         cmd.parse(argc, argv);
 
@@ -58,6 +94,10 @@ cl_options read_options(int argc, char** argv) {
         options.tfinal = tfinal_arg.getValue();
         options.dt = dt_arg.getValue();
         options.all_to_all = all_to_all_arg.getValue();
+        options.probe_ratio = probe_ratio_arg.getValue();
+        options.probe_soma_only = probe_soma_only_arg.getValue();
+        options.trace_prefix = trace_prefix_arg.getValue();
+        options.trace_max_gid = trace_max_gid_arg.getValue();
     }
     // catch any exceptions in command line handling
     catch (TCLAP::ArgException& e) {
@@ -100,6 +140,14 @@ std::ostream& operator<<(std::ostream& o, const cl_options& options) {
     o << "  simulation time      : " << options.tfinal << "\n";
     o << "  dt                   : " << options.dt << "\n";
     o << "  all to all network   : " << (options.all_to_all ? "yes" : "no") << "\n";
+    o << "  probe ratio          : " << options.probe_ratio << "\n";
+    o << "  probe soma only      : " << (options.probe_soma_only ? "yes" : "no") << "\n";
+    o << "  trace prefix         : " << options.trace_prefix << "\n";
+    o << "  trace max gid        : ";
+    if (options.trace_max_gid) {
+       o << *options.trace_max_gid;
+    }
+    o << "\n";
     o << "  input file name      : " << options.ifname << "\n";
 
     return o;
diff --git a/miniapp/io.hpp b/miniapp/io.hpp
index dab584fe2a132f289bb9a2f1ae02711aa29ef5a4..71af61810670d7a1f226d3eec2dabfd2f38ff20e 100644
--- a/miniapp/io.hpp
+++ b/miniapp/io.hpp
@@ -6,6 +6,8 @@
 #include <stdexcept>
 #include <utility>
 
+#include <util/optional.hpp>
+
 namespace nest {
 namespace mc {
 namespace io {
@@ -20,6 +22,10 @@ struct cl_options {
     double tfinal;
     double dt;
     bool all_to_all;
+    bool probe_soma_only;
+    double probe_ratio;
+    std::string trace_prefix;
+    util::optional<unsigned> trace_max_gid;
 };
 
 class usage_error: public std::runtime_error {
diff --git a/miniapp/miniapp.cpp b/miniapp/miniapp.cpp
index 9b26ff86ef37f829667161afca27a129791de3ed..3e9d4dd227efbb90823b99db2fedd00cc94e4f81 100644
--- a/miniapp/miniapp.cpp
+++ b/miniapp/miniapp.cpp
@@ -32,7 +32,7 @@ using model_type = model<lowered_cell>;
 using sample_trace_type = sample_trace<model_type::time_type, model_type::value_type>;
 
 void banner();
-std::unique_ptr<recipe> make_recipe(const io::cl_options&);
+std::unique_ptr<recipe> make_recipe(const io::cl_options&, const probe_distribution&);
 std::unique_ptr<sample_trace_type> make_trace(cell_member_type probe_id, probe_spec probe);
 std::pair<cell_gid_type, cell_gid_type> distribute_cells(cell_size_type ncells);
 
@@ -53,7 +53,12 @@ int main(int argc, char** argv) {
                   << std::ceil(options.tfinal / options.dt) << " steps of "
                   << options.dt << " ms" << std::endl;
 
-        auto recipe = make_recipe(options);
+        // determine what to attach probes to
+        probe_distribution pdist;
+        pdist.proportion = options.probe_ratio;
+        pdist.all_segments = !options.probe_soma_only;
+
+        auto recipe = make_recipe(options, pdist);
         auto cell_range = distribute_cells(recipe->num_cells());
 
         // build model from recipe
@@ -69,6 +74,10 @@ int main(int argc, char** argv) {
         std::vector<std::unique_ptr<sample_trace_type>> traces;
         const model_type::time_type sample_dt = 0.1;
         for (auto probe: m.probes()) {
+            if (options.trace_max_gid && probe.id.gid>*options.trace_max_gid) {
+                continue;
+            }
+
             traces.push_back(make_trace(probe.id, probe.probe));
             m.attach_sampler(probe.id, make_trace_sampler(traces.back().get(),sample_dt));
         }
@@ -81,7 +90,7 @@ int main(int argc, char** argv) {
 
         // save traces
         for (const auto& trace: traces) {
-            write_trace_json(*trace.get());
+            write_trace_json(*trace.get(), options.trace_prefix);
         }
     }
     catch (io::usage_error& e) {
@@ -119,7 +128,7 @@ void banner() {
     std::cout << "====================\n";
 }
 
-std::unique_ptr<recipe> make_recipe(const io::cl_options& options) {
+std::unique_ptr<recipe> make_recipe(const io::cl_options& options, const probe_distribution& pdist) {
     basic_recipe_param p;
 
     p.num_compartments = options.compartments_per_segment;
@@ -127,17 +136,17 @@ std::unique_ptr<recipe> make_recipe(const io::cl_options& options) {
     p.synapse_type = options.syn_type;
 
     if (options.all_to_all) {
-        return make_basic_kgraph_recipe(options.cells, p);
+        return make_basic_kgraph_recipe(options.cells, p, pdist);
     }
     else {
-        return make_basic_rgraph_recipe(options.cells, p);
+        return make_basic_rgraph_recipe(options.cells, p, pdist);
     }
 }
 
 std::unique_ptr<sample_trace_type> make_trace(cell_member_type probe_id, probe_spec probe) {
     std::string name = "";
     std::string units = "";
-    
+
     switch (probe.kind) {
     case probeKind::membrane_voltage:
         name = "v";
diff --git a/miniapp/miniapp_recipes.cpp b/miniapp/miniapp_recipes.cpp
index 22c59bd851a049e448784b9cfdd635d7e7a96970..742951dff6df83cb13c2f13af6e2d1ace2ae97eb 100644
--- a/miniapp/miniapp_recipes.cpp
+++ b/miniapp/miniapp_recipes.cpp
@@ -76,13 +76,15 @@ public:
         EXPECTS(cell.detectors().size()==cc.num_sources);
 
         // add probes
-        unsigned n_probe_segs = pdist_.all_segments? basic_cell_segments: 1u;
-        for (unsigned i = 0; i<n_probe_segs; ++i) {
-            if (pdist_.membrane_voltage) {
-                cell.add_probe({{i, i? 0.5: 0.0}, mc::probeKind::membrane_voltage});
-            }
-            if (pdist_.membrane_current) {
-                cell.add_probe({{i, i? 0.5: 0.0}, mc::probeKind::membrane_current});
+        if (cc.num_probes) {
+            unsigned n_probe_segs = pdist_.all_segments? basic_cell_segments: 1u;
+            for (unsigned i = 0; i<n_probe_segs; ++i) {
+                if (pdist_.membrane_voltage) {
+                    cell.add_probe({{i, i? 0.5: 0.0}, mc::probeKind::membrane_voltage});
+                }
+                if (pdist_.membrane_current) {
+                    cell.add_probe({{i, i? 0.5: 0.0}, mc::probeKind::membrane_current});
+                }
             }
         }
         EXPECTS(cell.probes().size()==cc.num_probes);
diff --git a/src/algorithms.hpp b/src/algorithms.hpp
index 7789b24156d403ba702404ccf67a67d0b2cfcedf..5456417ddaea0e0fe6c4e777a0fa8ebf3344c2ed 100644
--- a/src/algorithms.hpp
+++ b/src/algorithms.hpp
@@ -121,49 +121,42 @@ bool is_positive(C const& c)
 }
 
 template<typename C>
-bool has_contiguous_segments(const C& parent_index)
+std::vector<typename C::value_type> child_count(const C& parent_index)
 {
     static_assert(
         std::is_integral<typename C::value_type>::value,
         "integral type required"
     );
 
-    if (!is_minimal_degree(parent_index)) {
-        return false;
-    }
-
-    int n = parent_index.size();
-    std::vector<bool> is_leaf(n, false);
-
-    for(auto i=1; i<n; ++i) {
-        auto p = parent_index[i];
-        if(is_leaf[p]) {
-            return false;
-        }
-
-        if(p != decltype(p)(i-1)) {
-            // we have a branch and i-1 is a leaf node
-            is_leaf[i-1] = true;
-        }
+    std::vector<typename C::value_type> count(parent_index.size(), 0);
+    for (auto i = 1u; i < parent_index.size(); ++i) {
+        ++count[parent_index[i]];
     }
 
-    return true;
+    return count;
 }
 
 template<typename C>
-std::vector<typename C::value_type> child_count(const C& parent_index)
+bool has_contiguous_compartments(const C& parent_index)
 {
     static_assert(
         std::is_integral<typename C::value_type>::value,
         "integral type required"
     );
 
-    std::vector<typename C::value_type> count(parent_index.size(), 0);
-    for (std::size_t i = 1; i < parent_index.size(); ++i) {
-        ++count[parent_index[i]];
+    if (!is_minimal_degree(parent_index)) {
+        return false;
     }
 
-    return count;
+    auto num_child = child_count(parent_index);
+    for (auto i = 1u; i < parent_index.size(); ++i) {
+        auto p = parent_index[i];
+        if (num_child[p] == 1 && p != i-1) {
+            return false;
+        }
+    }
+
+    return true;
 }
 
 template<typename C>
@@ -174,7 +167,7 @@ std::vector<typename C::value_type> branches(const C& parent_index)
         "integral type required"
     );
 
-    //EXPECTS(has_contiguous_segments(parent_index));
+    EXPECTS(has_contiguous_compartments(parent_index));
 
     std::vector<typename C::value_type> branch_index;
     if (parent_index.empty()) {
@@ -249,8 +242,8 @@ std::vector<typename C::value_type> make_parent_index(
         return {};
     }
 
-    EXPECTS(parent_index.size() == unsigned(branch_index.back()));
-    //EXPECTS(has_contiguous_segments(parent_index));
+    EXPECTS(parent_index.size() == branch_index.back());
+    EXPECTS(has_contiguous_compartments(parent_index));
     EXPECTS(is_strictly_monotonic_increasing(branch_index));
 
     // expand the branch index
diff --git a/src/communication/communicator.hpp b/src/communication/communicator.hpp
index 871bf65266da7c7ffcc962a41f9913d93fa89fc2..8c72430f5c4646ce7747c76cac088bee65a58df8 100644
--- a/src/communication/communicator.hpp
+++ b/src/communication/communicator.hpp
@@ -5,11 +5,12 @@
 #include <vector>
 #include <random>
 
+#include <spike.hpp>
+#include <util/double_buffer.hpp>
 #include <algorithms.hpp>
 #include <connection.hpp>
 #include <event_queue.hpp>
 #include <spike.hpp>
-#include <threading/threading.hpp>
 #include <util/debug.hpp>
 
 namespace nest {
@@ -29,43 +30,50 @@ namespace communication {
 template <typename Time, typename CommunicationPolicy>
 class communicator {
 public:
+    using communication_policy_type = CommunicationPolicy;
     using id_type = cell_gid_type;
     using time_type = Time;
-    using communication_policy_type = CommunicationPolicy;
-
     using spike_type = spike<cell_member_type, time_type>;
+    using connection_type = connection<time_type>;
+
+    /// per-cell group lists of events to be delivered
+    using event_queue =
+        std::vector<postsynaptic_spike_event<time_type>>;
 
     communicator() = default;
 
+    // TODO
     // for now, still assuming one-to-one association cells <-> groups,
     // so that 'group' gids as represented by their first cell gid are
     // contiguous.
     communicator(id_type cell_from, id_type cell_to):
         cell_gid_from_(cell_from), cell_gid_to_(cell_to)
-    {
-        auto num_groups_local_ = cell_gid_to_-cell_gid_from_;
+    {}
 
-        // create an event queue for each target group
-        events_.resize(num_groups_local_);
+    cell_local_size_type num_groups_local() const
+    {
+        return cell_gid_to_-cell_gid_from_;
     }
 
-
-    void add_connection(connection<time_type> con) {
+    void add_connection(connection_type con) {
         EXPECTS(is_local_cell(con.destination().gid));
         connections_.push_back(con);
     }
 
+    /// returns true if the cell with gid is on the domain of the caller
     bool is_local_cell(id_type gid) const {
         return gid>=cell_gid_from_ && gid<cell_gid_to_;
     }
 
-    // builds the optimized data structure
+    /// builds the optimized data structure
+    /// must be called after all connections have been added
     void construct() {
         if (!std::is_sorted(connections_.begin(), connections_.end())) {
             std::sort(connections_.begin(), connections_.end());
         }
     }
 
+    /// the minimum delay of all connections in the global network.
     time_type min_delay() {
         auto local_min = std::numeric_limits<time_type>::max();
         for (auto& con : connections_) {
@@ -75,31 +83,22 @@ public:
         return communication_policy_.min(local_min);
     }
 
-    void add_spike(spike_type s) {
-        thread_spikes().push_back(s);
-    }
-
-    void add_spikes(const std::vector<spike_type>& s) {
-        auto& v = thread_spikes();
-        v.insert(v.end(), s.begin(), s.end());
-    }
-
-    std::vector<spike_type>& thread_spikes() {
-        return thread_spikes_.local();
-    }
-
-    void exchange() {
-        // global all-to-all to gather a local copy of the global spike list
-        // on each node
-        auto global_spikes = communication_policy_.gather_spikes(local_spikes());
+    /// Perform exchange of spikes.
+    ///
+    /// Takes as input the list of local_spikes that were generated on the calling domain.
+    ///
+    /// Returns a vector of event queues, with one queue for each local cell group. The
+    /// events in each queue are all events that must be delivered to targets in that cell
+    /// group as a result of the global spike exchange.
+    std::vector<event_queue> exchange(const std::vector<spike_type>& local_spikes) {
+        // global all-to-all to gather a local copy of the global spike list on each node.
+        auto global_spikes = communication_policy_.gather_spikes( local_spikes );
         num_spikes_ += global_spikes.size();
-        clear_thread_spike_buffers();
 
-        for (auto& q : events_) {
-            q.clear();
-        }
+        // check each global spike in turn to see it generates local events.
+        // if so, make the events and insert them into the appropriate event list.
+        auto queues = std::vector<event_queue>(num_groups_local());
 
-        // check all global spikes to see if they will generate local events
         for (auto spike : global_spikes) {
             // search for targets
             auto targets =
@@ -110,18 +109,18 @@ public:
             // generate an event for each target
             for (auto it=targets.first; it!=targets.second; ++it) {
                 auto gidx = cell_group_index(it->destination().gid);
-                events_[gidx].push_back(it->make_event(spike));
+                queues[gidx].push_back(it->make_event(spike));
             }
         }
+
+        return queues;
     }
 
+    /// Returns the total number of global spikes over the duration
+    /// of the simulation
     uint64_t num_spikes() const { return num_spikes_; }
 
-    const std::vector<postsynaptic_spike_event<time_type>>& queue(int i) const {
-        return events_[i];
-    }
-
-    const std::vector<connection<time_type>>& connections() const {
+    const std::vector<connection_type>& connections() const {
         return connections_;
     }
 
@@ -129,28 +128,6 @@ public:
         return communication_policy_;
     }
 
-    std::vector<spike_type> local_spikes() {
-        std::vector<spike_type> spikes;
-        for (auto& v : thread_spikes_) {
-            spikes.insert(spikes.end(), v.begin(), v.end());
-        }
-        return spikes;
-    }
-
-    void clear_thread_spike_buffers() {
-        for (auto& v : thread_spikes_) {
-            v.clear();
-        }
-    }
-
-    void reset() {
-        // remove all in-flight spikes/events
-        clear_thread_spike_buffers();
-        for (auto& evbuf: events_) {
-            evbuf.clear();
-        }
-    }
-
 private:
     std::size_t cell_group_index(cell_gid_type cell_gid) const {
         // this will be more elaborate when there is more than one cell per cell group
@@ -158,24 +135,7 @@ private:
         return cell_gid-cell_gid_from_;
     }
 
-    //
-    //  both of these can be fixed with double buffering
-    //
-    // FIXME : race condition on the thread_spikes_ buffers when exchange() modifies/access them
-    //         ... other threads will be pushing to them simultaneously
-    // FIXME : race condition on the group-specific event queues when exchange pushes to them
-    //         ... other threads will be accessing them to update their event queues
-
-    // thread private storage for accumulating spikes
-    using local_spike_store_type =
-        nest::mc::threading::enumerable_thread_specific<std::vector<spike_type>>;
-    local_spike_store_type thread_spikes_;
-
-    std::vector<connection<time_type>> connections_;
-    std::vector<std::vector<postsynaptic_spike_event<time_type>>> events_;
-
-    // for keeping track of how time is spent where
-    //util::Profiler profiler_;
+    std::vector<connection_type> connections_;
 
     communication_policy_type communication_policy_;
 
diff --git a/src/model.hpp b/src/model.hpp
index 3812a44bfffaa21397d12953c93fcd13bb3843d9..84dd84298a78418ce882b68a29f2211a6e50401b 100644
--- a/src/model.hpp
+++ b/src/model.hpp
@@ -6,10 +6,11 @@
 #include <common_types.hpp>
 #include <cell.hpp>
 #include <cell_group.hpp>
-#include <communication/communicator.hpp>
-#include <communication/global_policy.hpp>
 #include <fvm_cell.hpp>
 #include <recipe.hpp>
+#include <thread_private_spike_store.hpp>
+#include <communication/communicator.hpp>
+#include <communication/global_policy.hpp>
 #include <profiling/profiler.hpp>
 
 #include "trace_sampler.hpp"
@@ -36,9 +37,10 @@ public:
         cell_to_(cell_to),
         communicator_(cell_from, cell_to)
     {
+        // generate the cell groups in parallel, with one task per cell group
         cell_groups_ = std::vector<cell_group_type>{cell_to_-cell_from_};
-
         threading::parallel_vector<probe_record> probes;
+
         threading::parallel_for::apply(cell_from_, cell_to_,
             [&](cell_gid_type i) {
                 PE("setup", "cells");
@@ -54,8 +56,10 @@ public:
                 PL(2);
             });
 
+        // insert probes
         probes_.assign(probes.begin(), probes.end());
 
+        // generate the network connections
         for (cell_gid_type i=cell_from_; i<cell_to_; ++i) {
             for (const auto& cc: rec.connections_on(i)) {
                 connection<time_type> conn{cc.source, cc.dest, cc.weight, cc.delay};
@@ -63,6 +67,12 @@ public:
             }
         }
         communicator_.construct();
+
+        // Allocate an empty queue buffer for each cell group
+        // These must be set initially to ensure that a queue is available for each
+        // cell group for the first time step.
+        current_events().resize(num_groups());
+        future_events().resize(num_groups());
     }
 
     void reset() {
@@ -74,41 +84,74 @@ public:
     }
 
     time_type run(time_type tfinal, time_type dt) {
-        time_type min_delay = communicator_.min_delay();
-        while (t_<tfinal) {
-            auto tuntil = std::min(t_+min_delay, tfinal);
-            threading::parallel_for::apply(
-                0u, cell_groups_.size(),
-                [&](unsigned i) {
-                    auto& group = cell_groups_[i];
-
-                    PE("stepping","events");
-                    group.enqueue_events(communicator_.queue(i));
-                    PL();
+        // Calculate the size of the largest possible time integration interval
+        // before communication of spikes is required.
+        // If spike exchange and cell update are serialized, this is the
+        // minimum delay of the network, however we use half this period
+        // to overlap communication and computation.
+        time_type t_interval = communicator_.min_delay()/2;
 
-                    group.advance(tuntil, dt);
-
-                    PE("events");
-                    communicator_.add_spikes(group.spikes());
-                    group.clear_spikes();
-                    PL(2);
-                });
+        while (t_<tfinal) {
+            auto tuntil = std::min(t_+t_interval, tfinal);
+
+            event_queues_.exchange();
+            local_spikes_.exchange();
+
+            // empty the spike buffers for the current integration period.
+            // these buffers will store the new spikes generated in update_cells.
+            current_spikes().clear();
+
+            // task that updates cell state in parallel.
+            auto update_cells = [&] () {
+                threading::parallel_for::apply(
+                    0u, cell_groups_.size(),
+                    [&](unsigned i) {
+                        auto &group = cell_groups_[i];
+
+                        PE("stepping","events");
+                        group.enqueue_events(current_events()[i]);
+                        PL();
+
+                        group.advance(tuntil, dt);
+
+                        PE("events");
+                        current_spikes().insert(group.spikes());
+                        group.clear_spikes();
+                        PL(2);
+                    });
+            };
+
+            // task that performs spike exchange with the spikes generated in
+            // the previous integration period, generating the postsynaptic
+            // events that must be delivered at the start of the next
+            // integration period at the latest.
+            auto exchange = [&] () {
+                PE("stepping", "exchange");
+                auto local_spikes = previous_spikes().gather();
+                future_events() = communicator_.exchange(local_spikes);
+                PL(2);
+            };
 
-            PE("stepping", "exchange");
-            communicator_.exchange();
-            PL(2);
+            // run the tasks, overlapping if the threading model and number of
+            // available threads permits it.
+            threading::task_group g;
+            g.run(exchange);
+            g.run(update_cells);
+            g.wait();
 
             t_ = tuntil;
         }
         return t_;
     }
 
+    // only thread safe if called outside the run() method
     void add_artificial_spike(cell_member_type source) {
         add_artificial_spike(source, t_);
     }
 
+    // only thread safe if called outside the run() method
     void add_artificial_spike(cell_member_type source, time_type tspike) {
-        communicator_.add_spike({source, tspike});
+        current_spikes().get().push_back({source, tspike});
     }
 
     void attach_sampler(cell_member_type probe_id, sampler_function f, time_type tfrom = 0) {
@@ -122,6 +165,7 @@ public:
     const std::vector<probe_record>& probes() const { return probes_; }
 
     std::size_t num_spikes() const { return communicator_.num_spikes(); }
+    std::size_t num_groups() const { return cell_groups_.size(); }
 
 private:
     cell_gid_type cell_from_;
@@ -130,6 +174,35 @@ private:
     std::vector<cell_group_type> cell_groups_;
     communicator_type communicator_;
     std::vector<probe_record> probes_;
+    using spike_type = typename communicator_type::spike_type;
+
+    using event_queue_type = typename communicator_type::event_queue;
+    util::double_buffer< std::vector<event_queue_type> > event_queues_;
+
+    using local_spike_store_type = thread_private_spike_store<time_type>;
+    util::double_buffer< local_spike_store_type > local_spikes_;
+
+    // Convenience functions that map the spike buffers and event queues onto
+    // the appropriate integration interval.
+    //
+    // To overlap communication and computation, integration intervals of
+    // size Delta/2 are used, where Delta is the minimum delay in the global
+    // system.
+    // From the frame of reference of the current integration period we
+    // define three intervals: previous, current and future
+    // Then we define the following :
+    //      current_spikes : spikes generated in the current interval
+    //      previous_spikes: spikes generated in the preceding interval
+    //      current_events : events to be delivered at the start of
+    //                       the current interval
+    //      future_events  : events to be delivered at the start of
+    //                       the next interval
+
+    local_spike_store_type& current_spikes()  { return local_spikes_.get(); }
+    local_spike_store_type& previous_spikes() { return local_spikes_.other(); }
+
+    std::vector<event_queue_type>& current_events()  { return event_queues_.get(); }
+    std::vector<event_queue_type>& future_events()   { return event_queues_.other(); }
 };
 
 } // namespace mc
diff --git a/src/swcio.cpp b/src/swcio.cpp
index 3f38f8e791308819ac2fe3eeecde4c78ab585799..db8001be40447864ce5c6c5974f274fb516afcf8 100644
--- a/src/swcio.cpp
+++ b/src/swcio.cpp
@@ -261,7 +261,7 @@ swc_record_range_clean::swc_record_range_clean(std::istream& is)
         parent_list.push_back(records_[i].parent());
     }
 
-    if (!nest::mc::algorithms::has_contiguous_segments(parent_list)) {
+    if (!nest::mc::algorithms::has_contiguous_compartments(parent_list)) {
         throw swc_parse_error("branches are not contiguously numbered", 0);
     }
 }
diff --git a/src/thread_private_spike_store.hpp b/src/thread_private_spike_store.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1e14ab104619a42b8aa9f014172bb5716576017c
--- /dev/null
+++ b/src/thread_private_spike_store.hpp
@@ -0,0 +1,75 @@
+#pragma once
+
+#include <vector>
+
+#include <common_types.hpp>
+#include <spike.hpp>
+#include <threading/threading.hpp>
+
+namespace nest {
+namespace mc {
+
+/// Handles the complexity of managing thread private buffers of spikes.
+/// Internally stores one thread private buffer of spikes for each hardware thread.
+/// This can be accessed directly using the get() method, which returns a reference to
+/// The thread private buffer of the calling thread.
+/// The insert() and gather() methods add a vector of spikes to the buffer,
+/// and collate all of the buffers into a single vector respectively.
+template <typename Time>
+class thread_private_spike_store {
+public :
+    using id_type = cell_gid_type;
+    using time_type = Time;
+    using spike_type = spike<cell_member_type, time_type>;
+
+    /// Collate all of the individual buffers into a single vector of spikes.
+    /// Does not modify the buffer contents.
+    std::vector<spike_type> gather() const {
+        std::vector<spike_type> spikes;
+        unsigned num_spikes = 0u;
+        for (auto& b : buffers_) {
+            num_spikes += b.size();
+        }
+        spikes.reserve(num_spikes);
+
+        for (auto& b : buffers_) {
+            spikes.insert(spikes.begin(), b.begin(), b.end());
+        }
+
+        return spikes;
+    }
+
+    /// Return a reference to the thread private buffer of the calling thread
+    std::vector<spike_type>& get() {
+        return buffers_.local();
+    }
+
+    /// Return a reference to the thread private buffer of the calling thread
+    const std::vector<spike_type>& get() const {
+        return buffers_.local();
+    }
+
+    /// Clear all of the thread private buffers
+    void clear() {
+        for (auto& b : buffers_) {
+            b.clear();
+        }
+    }
+
+    /// Append the passed spikes to the end of the thread private buffer of the
+    /// calling thread
+    void insert(const std::vector<spike_type>& spikes) {
+        auto& buff = get();
+        buff.insert(buff.end(), spikes.begin(), spikes.end());
+    }
+
+private :
+    /// thread private storage for accumulating spikes
+    using local_spike_store_type =
+        threading::enumerable_thread_specific<std::vector<spike_type>>;
+
+    local_spike_store_type buffers_;
+};
+
+} // namespace mc
+} // namespace nest
diff --git a/src/threading/serial.hpp b/src/threading/serial.hpp
index 8d9c4d64fd84805ed0909ad704ffc192bd0da748..c18d4800e3c457e140f0fe6d2ca671aa6ccac241 100644
--- a/src/threading/serial.hpp
+++ b/src/threading/serial.hpp
@@ -19,6 +19,8 @@ namespace threading {
 template <typename T>
 class enumerable_thread_specific {
     std::array<T, 1> data;
+    using iterator_type = typename std::array<T, 1>::iterator;
+    using const_iterator_type = typename std::array<T, 1>::const_iterator;
 
     public :
 
@@ -37,11 +39,14 @@ class enumerable_thread_specific {
 
     auto size() -> decltype(data.size()) const { return data.size(); }
 
-    auto begin() -> decltype(data.begin()) { return data.begin(); }
-    auto end()   -> decltype(data.end())   { return data.end(); }
+    iterator_type begin() { return data.begin(); }
+    iterator_type end()   { return data.end(); }
 
-    auto cbegin() -> decltype(data.cbegin()) const { return data.cbegin(); }
-    auto cend()   -> decltype(data.cend())   const { return data.cend(); }
+    const_iterator_type begin() const { return data.begin(); }
+    const_iterator_type end()   const { return data.end(); }
+
+    const_iterator_type cbegin() const { return data.cbegin(); }
+    const_iterator_type cend()   const { return data.cend(); }
 };
 
 
@@ -83,6 +88,34 @@ struct timer {
 
 constexpr bool multithreaded() { return false; }
 
+/// Proxy for tbb task group.
+/// The tbb version launches tasks asynchronously, returning control to the
+/// caller. The serial version implemented here simply runs the task, before
+/// returning control, effectively serializing all asynchronous calls.
+class task_group {
+public:
+    task_group() = default;
+
+    template<typename Func>
+    void run(const Func& f) {
+        f();
+    }
+
+    template<typename Func>
+    void run_and_wait(const Func& f) {
+        f();
+    }
+
+    void wait()
+    {}
+
+    bool is_canceling() {
+        return false;
+    }
+
+    void cancel()
+    {}
+};
 
 } // threading
 } // mc
diff --git a/src/threading/tbb.hpp b/src/threading/tbb.hpp
index 8e0086741cac1d51e02e9fa148e9eaa3f3f837a3..853ceefde731cb1cd4db323541132c935011c73a 100644
--- a/src/threading/tbb.hpp
+++ b/src/threading/tbb.hpp
@@ -49,6 +49,8 @@ constexpr bool multithreaded() { return true; }
 template <typename T>
 using parallel_vector = tbb::concurrent_vector<T>;
 
+using task_group = tbb::task_group;
+
 } // threading
 } // mc
 } // nest
diff --git a/src/util/double_buffer.hpp b/src/util/double_buffer.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..31cffa1babef2ced0b843b4d3e375678612528b2
--- /dev/null
+++ b/src/util/double_buffer.hpp
@@ -0,0 +1,66 @@
+#pragma once
+
+#include <array>
+#include <atomic>
+
+#include <util/debug.hpp>
+
+namespace nest {
+namespace mc {
+namespace util {
+
+/// double buffer with thread safe exchange/flip operation.
+template <typename T>
+class double_buffer {
+private:
+    std::atomic<int> index_;
+    std::array<T, 2> buffers_;
+
+    int other_index() {
+        return index_ ? 0 : 1;
+    }
+
+public:
+    using value_type = T;
+
+    double_buffer() :
+        index_(0)
+    {}
+
+    /// remove the copy and move constructors which won't work with std::atomic
+    double_buffer(double_buffer&&) = delete;
+    double_buffer(const double_buffer&) = delete;
+    double_buffer& operator=(const double_buffer&) = delete;
+    double_buffer& operator=(double_buffer&&) = delete;
+
+    /// flip the buffers in a thread safe manner
+    /// n calls to exchange will always result in n flips
+    void exchange() {
+        // use operator^= which is overloaded by std::atomic<>
+        index_ ^= 1;
+    }
+
+    /// get the current/front buffer
+    value_type& get() {
+        return buffers_[index_];
+    }
+
+    /// get the current/front buffer
+    const value_type& get() const {
+        return buffers_[index_];
+    }
+
+    /// get the back buffer
+    value_type& other() {
+        return buffers_[other_index()];
+    }
+
+    /// get the back buffer
+    const value_type& other() const {
+        return buffers_[other_index()];
+    }
+};
+
+} // namespace util
+} // namespace mc
+} // namespace nest
diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt
index 4ba5bb8b0be6764e84fb24ea1c16ee803f6bc516..fb1b9369d4e38498c8953fc0ce2f16c1dbc715dc 100644
--- a/tests/unit/CMakeLists.txt
+++ b/tests/unit/CMakeLists.txt
@@ -11,6 +11,7 @@ set(HEADERS
 set(TEST_SOURCES
     # unit tests
     test_algorithms.cpp
+    test_double_buffer.cpp
     test_cell.cpp
     test_compartments.cpp
     test_event_queue.cpp
@@ -26,6 +27,7 @@ set(TEST_SOURCES
     test_probe.cpp
     test_segment.cpp
     test_spikes.cpp
+    test_spike_store.cpp
     test_stimulus.cpp
     test_swcio.cpp
     test_synapses.cpp
@@ -45,12 +47,12 @@ foreach(target ${TARGETS})
     target_link_libraries(${target} LINK_PUBLIC cellalgo gtest)
 
     if(WITH_TBB)
-	target_link_libraries(${target} LINK_PUBLIC ${TBB_LIBRARIES})
+    target_link_libraries(${target} LINK_PUBLIC ${TBB_LIBRARIES})
     endif()
 
     if(WITH_MPI)
-	target_link_libraries(${target} LINK_PUBLIC ${MPI_C_LIBRARIES})
-	set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS "${MPI_C_LINK_FLAGS}")
+    target_link_libraries(${target} LINK_PUBLIC ${MPI_C_LIBRARIES})
+    set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS "${MPI_C_LINK_FLAGS}")
     endif()
 
     set_target_properties(${target}
diff --git a/tests/unit/test_algorithms.cpp b/tests/unit/test_algorithms.cpp
index badaabffb605986578cbc15b9ed40b597a0e95ff..ebe19c3752e9e4eacb23008e467bca9a1fd95f79 100644
--- a/tests/unit/test_algorithms.cpp
+++ b/tests/unit/test_algorithms.cpp
@@ -172,7 +172,7 @@ TEST(algorithms, is_positive)
     );
 }
 
-TEST(algorithms, has_contiguous_segments)
+TEST(algorithms, has_contiguous_compartments)
 {
     //
     //       0
@@ -186,7 +186,7 @@ TEST(algorithms, has_contiguous_segments)
     //   5       6
     //
     EXPECT_FALSE(
-        nest::mc::algorithms::has_contiguous_segments(
+        nest::mc::algorithms::has_contiguous_compartments(
             std::vector<int>{0, 0, 1, 2, 2, 3, 4, 2}
         )
     );
@@ -203,7 +203,7 @@ TEST(algorithms, has_contiguous_segments)
     //   4       7
     //
     EXPECT_FALSE(
-        nest::mc::algorithms::has_contiguous_segments(
+        nest::mc::algorithms::has_contiguous_compartments(
             std::vector<int>{0, 0, 1, 2, 3, 2, 2, 5}
         )
     );
@@ -220,7 +220,7 @@ TEST(algorithms, has_contiguous_segments)
     //   4       6
     //
     EXPECT_TRUE(
-        nest::mc::algorithms::has_contiguous_segments(
+        nest::mc::algorithms::has_contiguous_compartments(
             std::vector<int>{0, 0, 1, 2, 3, 2, 5, 2}
         )
     );
@@ -237,21 +237,34 @@ TEST(algorithms, has_contiguous_segments)
     //   4       6
     //
     EXPECT_TRUE(
-        nest::mc::algorithms::has_contiguous_segments(
+        nest::mc::algorithms::has_contiguous_compartments(
             std::vector<int>{0, 0, 1, 2, 3, 2, 5, 1}
         )
     );
 
+    //
+    //     0
+    //    / \
+    //   1   2
+    //  / \
+    // 3   4
+    //
+    EXPECT_TRUE(
+        nest::mc::algorithms::has_contiguous_compartments(
+            std::vector<int>{0, 0, 0, 1, 1}
+        )
+    );
+
     // Soma-only list
     EXPECT_TRUE(
-        nest::mc::algorithms::has_contiguous_segments(
+        nest::mc::algorithms::has_contiguous_compartments(
             std::vector<int>{0}
         )
     );
 
     // Empty list
     EXPECT_TRUE(
-        nest::mc::algorithms::has_contiguous_segments(
+        nest::mc::algorithms::has_contiguous_compartments(
             std::vector<int>{}
         )
     );
diff --git a/tests/unit/test_double_buffer.cpp b/tests/unit/test_double_buffer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1689cc2faac17331694c78830c22cd1ea57777fe
--- /dev/null
+++ b/tests/unit/test_double_buffer.cpp
@@ -0,0 +1,58 @@
+#include "gtest.h"
+
+#include <util/double_buffer.hpp>
+
+// not much to test here: just test that values passed into the constructor
+// are correctly stored in members
+TEST(double_buffer, exchange_and_get)
+{
+    using namespace nest::mc::util;
+
+    double_buffer<int> buf;
+
+    buf.get() = 2134;
+    buf.exchange();
+    buf.get() = 8990;
+    buf.exchange();
+
+    EXPECT_EQ(buf.get(), 2134);
+    EXPECT_EQ(buf.other(), 8990);
+    buf.exchange();
+    EXPECT_EQ(buf.get(), 8990);
+    EXPECT_EQ(buf.other(), 2134);
+    buf.exchange();
+    EXPECT_EQ(buf.get(), 2134);
+    EXPECT_EQ(buf.other(), 8990);
+}
+
+TEST(double_buffer, assign_get_other)
+{
+    using namespace nest::mc::util;
+
+    double_buffer<std::string> buf;
+
+    buf.get()   = "1";
+    buf.other() = "2";
+
+    EXPECT_EQ(buf.get(), "1");
+    EXPECT_EQ(buf.other(), "2");
+}
+
+TEST(double_buffer, non_pod)
+{
+    using namespace nest::mc::util;
+
+    double_buffer<std::string> buf;
+
+    buf.get()   = "1";
+    buf.other() = "2";
+
+    EXPECT_EQ(buf.get(), "1");
+    EXPECT_EQ(buf.other(), "2");
+    buf.exchange();
+    EXPECT_EQ(buf.get(), "2");
+    EXPECT_EQ(buf.other(), "1");
+    buf.exchange();
+    EXPECT_EQ(buf.get(), "1");
+    EXPECT_EQ(buf.other(), "2");
+}
diff --git a/tests/unit/test_spike_store.cpp b/tests/unit/test_spike_store.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dd075f878bfccc7a7a07887e6736fcb2768e0237
--- /dev/null
+++ b/tests/unit/test_spike_store.cpp
@@ -0,0 +1,84 @@
+#include "gtest.h"
+
+#include <thread_private_spike_store.hpp>
+
+TEST(spike_store, insert)
+{
+    using store_type = nest::mc::thread_private_spike_store<float>;
+
+    store_type store;
+
+    // insert 3 spike events and check that they were inserted correctly
+    store.insert({
+        {{0,0}, 0.0f},
+        {{1,2}, 0.5f},
+        {{2,4}, 1.0f}
+    });
+
+    {
+        EXPECT_EQ(store.get().size(), 3u);
+        auto i = 0u;
+        for (auto& spike : store.get()) {
+            EXPECT_EQ(spike.source.gid,   i);
+            EXPECT_EQ(spike.source.index, 2*i);
+            EXPECT_EQ(spike.time, float(i)/2.f);
+            ++i;
+        }
+    }
+
+    // insert another 3 events, then check that they were appended to the
+    // original three events correctly
+    store.insert({
+        {{3,6},  1.5f},
+        {{4,8},  2.0f},
+        {{5,10}, 2.5f}
+    });
+
+    {
+        EXPECT_EQ(store.get().size(), 6u);
+        auto i = 0u;
+        for (auto& spike : store.get()) {
+            EXPECT_EQ(spike.source.gid,   i);
+            EXPECT_EQ(spike.source.index, 2*i);
+            EXPECT_EQ(spike.time, float(i)/2.f);
+            ++i;
+        }
+    }
+}
+
+TEST(spike_store, clear)
+{
+    using store_type = nest::mc::thread_private_spike_store<float>;
+
+    store_type store;
+
+    // insert 3 spike events
+    store.insert({
+        {{0,0}, 0.0f}, {{1,2}, 0.5f}, {{2,4}, 1.0f}
+    });
+    EXPECT_EQ(store.get().size(), 3u);
+    store.clear();
+    EXPECT_EQ(store.get().size(), 0u);
+}
+
+TEST(spike_store, gather)
+{
+    using store_type = nest::mc::thread_private_spike_store<float>;
+
+    store_type store;
+
+    auto spikes = std::vector<store_type::spike_type>
+        { {{0,0}, 0.0f}, {{1,2}, 0.5f}, {{2,4}, 1.0f} };
+
+    store.insert(spikes);
+    auto gathered_spikes = store.gather();
+
+    EXPECT_EQ(gathered_spikes.size(), spikes.size());
+
+    for(auto i=0u; i<spikes.size(); ++i) {
+        EXPECT_EQ(spikes[i].source.gid, gathered_spikes[i].source.gid);
+        EXPECT_EQ(spikes[i].source.index, gathered_spikes[i].source.index);
+        EXPECT_EQ(spikes[i].time, gathered_spikes[i].time);
+    }
+}
+