Repository: nrv-framework/NRV (language: python)

Issue:
retry this way
not everything changed with TC MR


Discussion / hints:

Fix patch:
diff --git a/.gitignore b/.gitignore
index 927bfc97..16978d20 100644
--- a/.gitignore
+++ b/.gitignore
@@ -207,3 +207,5 @@ tests/log_NRV_test.txt
 .vscode/settings.json
 tests/log_NRV_test.txt
 .vscode/*
+docs/_nrv/*
+
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e853e6dd..3b02c900 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,22 @@
 
 All notable changes to NRV are sumed up in this file.
 
+## [1.1.2] - 2024-09-??
+
+### Added
+- 'ui', a subpackage for user interface to separate from utils which are ment to stay internal.
+- Help restructuration to have a API description more user friendly.
+- nrv.CONFIG as a singleton object gathering configuration related data, parameters and methods.
+
+### Fixed
+- small fix in filter_freq to avoid filtering artifact
+
+### Removed
+- methods such as load_any_axon, load_any_electrode... (``load_any_`` + something) are deprecated, though not removed for backward compatibility. Please only use ``load_any`` function.
+
+
+
+
 ## [1.1.1] - 2024-08-05
 
 ### Added
diff --git a/ReadMe.md b/ReadMe.md
index d043e011..15b27e8e 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -6,7 +6,7 @@
 <!---[![DOI](xxxx)](xxx)-->
 <!---[![Build Status](xxxx)](xxx)-->
 
-<img src="docs/images/logo.png" alt="NRV" width="50%" height="auto" class="center">
+<img src="docs/__logo/logo.png" alt="NRV" width="50%" height="auto" class="center">
 
 # NRV
 *Python library for Peripheral Nervous System stimulation modeling*
diff --git a/TODO.md b/TODO.md
new file mode 100644
index 00000000..dc0eb2e9
--- /dev/null
+++ b/TODO.md
@@ -0,0 +1,16 @@
+LIST OF POINTS TO ADDRESS BEFORE NEXT VERSION
+---------------------------------------------
+THIS NEEDS TO BE DONE FOR BIOCAS AND EASE DEMOS!!! 
+
+* in backend/_NRV_Simulable, twice the same function (is_NRV_simulable and simulable), suppress the second
+
+* suppress maximum of * in the primary __init__.py
+
+* add top level docstring (cf. scipy init.py), and subprocess init files
+
+* add missing docstring functions (see utils...)
+
+* CL_simulation rename
+
+* test to deploy on binder -> build an environnement.yaml file with the requirements... to do in emergency !!!
+  * Almost done (technically working, need polish and truly demo file )
\ No newline at end of file
diff --git a/docs/__logo/__build/Archive-Regular.otf b/docs/__logo/__build/Archive-Regular.otf
new file mode 100644
index 00000000..05b41f79
Binary files /dev/null and b/docs/__logo/__build/Archive-Regular.otf differ
diff --git a/docs/__logo/__build/NRV_logo.drawio b/docs/__logo/__build/NRV_logo.drawio
new file mode 100644
index 00000000..e7889f25
--- /dev/null
+++ b/docs/__logo/__build/NRV_logo.drawio
@@ -0,0 +1,1422 @@
+<mxfile host="Electron" modified="2024-09-12T11:07:56.046Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.2.1 Chrome/112.0.5615.87 Electron/24.1.2 Safari/537.36" etag="vYyNVt_7ZiADmceIapiS" version="21.2.1" type="device" pages="5">
+  <diagram name="V B&amp;W" id="UrG_lCSkFQvfo-MhE2YY">
+    <mxGraphModel dx="2181" dy="834" grid="1" gridSize="1" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
+      <root>
+        <mxCell id="VeEIL8E56o80s0lGz2fd-0" />
+        <mxCell id="VeEIL8E56o80s0lGz2fd-1" parent="VeEIL8E56o80s0lGz2fd-0" />
+        <mxCell id="aMRiFwVcRuh5m5JrQTQK-43" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#000000;connectable=0;allowArrows=0;" parent="VeEIL8E56o80s0lGz2fd-1" vertex="1">
+          <mxGeometry x="568" y="577" width="510" height="448" as="geometry" />
+        </mxCell>
+        <mxCell id="aMRiFwVcRuh5m5JrQTQK-44" value="" style="rounded=0;whiteSpace=wrap;html=1;connectable=0;allowArrows=0;" parent="VeEIL8E56o80s0lGz2fd-1" vertex="1">
+          <mxGeometry x="-54" y="578" width="510" height="448" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-28" value="" style="group" parent="VeEIL8E56o80s0lGz2fd-1" vertex="1" connectable="0">
+          <mxGeometry x="83" y="161" width="310" height="350" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-2" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-28" source="3z2n9okl7X57A1Ji6MO4-26" target="3z2n9okl7X57A1Ji6MO4-27" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="110" y="265" as="sourcePoint" />
+            <mxPoint x="109" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-4" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-28" target="3z2n9okl7X57A1Ji6MO4-27" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="99" y="63" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-5" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;fontSize=19;strokeWidth=6;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-28" target="3z2n9okl7X57A1Ji6MO4-26" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="254" y="65" as="sourcePoint" />
+            <mxPoint x="169" y="93" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="209" y="68" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-6" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-28" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="210" y="69" as="sourcePoint" />
+            <mxPoint x="202" y="32" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-7" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-28" source="3z2n9okl7X57A1Ji6MO4-22" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="157" y="89" as="sourcePoint" />
+            <mxPoint x="39" y="274" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-8" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-28" source="3z2n9okl7X57A1Ji6MO4-23" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="73" y="134" as="sourcePoint" />
+            <mxPoint x="98" y="313" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-9" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-28" source="3z2n9okl7X57A1Ji6MO4-24" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="161" y="139" as="sourcePoint" />
+            <mxPoint x="197" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-10" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-28" source="3z2n9okl7X57A1Ji6MO4-25" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="263.5" y="133" as="sourcePoint" />
+            <mxPoint x="237" y="297" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-11" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-28" target="3z2n9okl7X57A1Ji6MO4-25" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="270" y="74" as="sourcePoint" />
+            <mxPoint x="216" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-12" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#000000;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#000000;gradientColor=#D0CEE2;" parent="3z2n9okl7X57A1Ji6MO4-28" vertex="1">
+          <mxGeometry x="140.40499999999997" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-13" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#000000;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#000000;gradientColor=#D0CEE2;" parent="3z2n9okl7X57A1Ji6MO4-28" vertex="1">
+          <mxGeometry x="133.0050000000001" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-14" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#000000;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#000000;gradientColor=#D0CEE2;" parent="3z2n9okl7X57A1Ji6MO4-28" vertex="1">
+          <mxGeometry x="140.375" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-15" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#000000;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#000000;gradientColor=#D0CEE2;" parent="3z2n9okl7X57A1Ji6MO4-28" vertex="1">
+          <mxGeometry x="132.97500000000014" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-16" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#000000;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#000000;gradientColor=#D0CEE2;" parent="3z2n9okl7X57A1Ji6MO4-28" vertex="1">
+          <mxGeometry x="140.375" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-17" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#000000;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#000000;gradientColor=#D0CEE2;" parent="3z2n9okl7X57A1Ji6MO4-28" vertex="1">
+          <mxGeometry x="132.97500000000014" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-22" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#000000;fillColor=#E6E6E6;labelBackgroundColor=none;fontColor=#000000;container=0;" parent="3z2n9okl7X57A1Ji6MO4-28" vertex="1">
+          <mxGeometry x="29" y="95" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-23" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#000000;fillColor=#E6E6E6;labelBackgroundColor=none;fontColor=#000000;container=0;" parent="3z2n9okl7X57A1Ji6MO4-28" vertex="1">
+          <mxGeometry x="88" y="253" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-24" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#000000;fillColor=#E6E6E6;labelBackgroundColor=none;fontColor=#000000;container=0;" parent="3z2n9okl7X57A1Ji6MO4-28" vertex="1">
+          <mxGeometry x="187" y="273" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-25" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#000000;fillColor=#E6E6E6;labelBackgroundColor=none;fontColor=#000000;container=0;" parent="3z2n9okl7X57A1Ji6MO4-28" vertex="1">
+          <mxGeometry x="227" y="87" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-26" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=6;aspect=fixed;fillColor=#E6E6E6;gradientDirection=radial;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;gradientColor=#000000;container=0;" parent="3z2n9okl7X57A1Ji6MO4-28" vertex="1">
+          <mxGeometry x="141" y="75" width="30" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-27" value="" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;size=100;rotation=90;strokeWidth=7;fillColor=none;connectable=0;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;container=0;" parent="3z2n9okl7X57A1Ji6MO4-28" vertex="1">
+          <mxGeometry x="-20" y="20" width="350" height="310" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-1" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=0;exitDx=0;exitDy=0;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-28" source="3z2n9okl7X57A1Ji6MO4-26" target="3z2n9okl7X57A1Ji6MO4-27" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="101" y="75" as="sourcePoint" />
+            <mxPoint x="96" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-3" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=0.177;exitY=0.81;exitDx=0;exitDy=0;exitPerimeter=0;fontSize=19;strokeWidth=6;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-28" source="3z2n9okl7X57A1Ji6MO4-27" target="3z2n9okl7X57A1Ji6MO4-26" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="174" y="312" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="97" y="64" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-19" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;N&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#000000;labelBackgroundColor=none;container=0;" parent="3z2n9okl7X57A1Ji6MO4-28" vertex="1">
+          <mxGeometry x="7" y="126" width="117.03846153846153" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-20" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;V&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#000000;labelBackgroundColor=none;container=0;" parent="3z2n9okl7X57A1Ji6MO4-28" vertex="1">
+          <mxGeometry x="183.99538461538464" y="125.99704607468618" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-21" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;R&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#000000;labelBackgroundColor=none;container=0;" parent="3z2n9okl7X57A1Ji6MO4-28" vertex="1">
+          <mxGeometry x="76.00076923076927" y="126" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-29" value="" style="group" parent="VeEIL8E56o80s0lGz2fd-1" vertex="1" connectable="0">
+          <mxGeometry x="509" y="129" width="310" height="350" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-51" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-29" source="3z2n9okl7X57A1Ji6MO4-48" target="3z2n9okl7X57A1Ji6MO4-49" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="110" y="265" as="sourcePoint" />
+            <mxPoint x="109" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-30" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-29" target="3z2n9okl7X57A1Ji6MO4-49" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="99" y="63" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-31" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;fontSize=19;strokeWidth=6;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-29" target="3z2n9okl7X57A1Ji6MO4-48" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="254" y="65" as="sourcePoint" />
+            <mxPoint x="169" y="93" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="209" y="68" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-32" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-29" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="210" y="69" as="sourcePoint" />
+            <mxPoint x="202" y="32" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-33" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-29" source="3z2n9okl7X57A1Ji6MO4-44" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="157" y="89" as="sourcePoint" />
+            <mxPoint x="39" y="274" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-34" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-29" source="3z2n9okl7X57A1Ji6MO4-45" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="73" y="134" as="sourcePoint" />
+            <mxPoint x="98" y="313" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-35" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-29" source="3z2n9okl7X57A1Ji6MO4-46" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="161" y="139" as="sourcePoint" />
+            <mxPoint x="197" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-36" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-29" source="3z2n9okl7X57A1Ji6MO4-47" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="263.5" y="133" as="sourcePoint" />
+            <mxPoint x="237" y="297" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-37" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-29" target="3z2n9okl7X57A1Ji6MO4-47" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="270" y="74" as="sourcePoint" />
+            <mxPoint x="216" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-38" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#000000;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#000000;gradientColor=#FF8000;" parent="3z2n9okl7X57A1Ji6MO4-29" vertex="1">
+          <mxGeometry x="140.40499999999997" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-39" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#000000;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#000000;gradientColor=#FF8000;" parent="3z2n9okl7X57A1Ji6MO4-29" vertex="1">
+          <mxGeometry x="133.0050000000001" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-40" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#000000;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#000000;gradientColor=#FF8000;" parent="3z2n9okl7X57A1Ji6MO4-29" vertex="1">
+          <mxGeometry x="140.375" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-41" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#000000;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#000000;gradientColor=#FF8000;" parent="3z2n9okl7X57A1Ji6MO4-29" vertex="1">
+          <mxGeometry x="132.97500000000014" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-42" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#000000;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#000000;gradientColor=#FF8000;" parent="3z2n9okl7X57A1Ji6MO4-29" vertex="1">
+          <mxGeometry x="140.375" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-43" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#000000;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#000000;gradientColor=#FF8000;" parent="3z2n9okl7X57A1Ji6MO4-29" vertex="1">
+          <mxGeometry x="132.97500000000014" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-44" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#000000;fillColor=#E6E6E6;labelBackgroundColor=none;fontColor=#000000;container=0;" parent="3z2n9okl7X57A1Ji6MO4-29" vertex="1">
+          <mxGeometry x="29" y="95" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-45" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#000000;fillColor=#E6E6E6;labelBackgroundColor=none;fontColor=#000000;container=0;" parent="3z2n9okl7X57A1Ji6MO4-29" vertex="1">
+          <mxGeometry x="88" y="253" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-46" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#000000;fillColor=#E6E6E6;labelBackgroundColor=none;fontColor=#000000;container=0;" parent="3z2n9okl7X57A1Ji6MO4-29" vertex="1">
+          <mxGeometry x="187" y="273" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-47" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#000000;fillColor=#E6E6E6;labelBackgroundColor=none;fontColor=#000000;container=0;" parent="3z2n9okl7X57A1Ji6MO4-29" vertex="1">
+          <mxGeometry x="227" y="87" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-48" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=6;aspect=fixed;fillColor=#FF8000;gradientDirection=radial;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;gradientColor=#000000;container=0;" parent="3z2n9okl7X57A1Ji6MO4-29" vertex="1">
+          <mxGeometry x="141" y="75" width="30" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-49" value="" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;size=100;rotation=90;strokeWidth=7;fillColor=none;connectable=0;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;container=0;" parent="3z2n9okl7X57A1Ji6MO4-29" vertex="1">
+          <mxGeometry x="-20" y="20" width="350" height="310" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-50" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=0;exitDx=0;exitDy=0;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-29" source="3z2n9okl7X57A1Ji6MO4-48" target="3z2n9okl7X57A1Ji6MO4-49" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="101" y="75" as="sourcePoint" />
+            <mxPoint x="96" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-52" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=0.177;exitY=0.81;exitDx=0;exitDy=0;exitPerimeter=0;fontSize=19;strokeWidth=6;strokeColor=#000000;labelBackgroundColor=none;fontColor=#000000;" parent="3z2n9okl7X57A1Ji6MO4-29" source="3z2n9okl7X57A1Ji6MO4-49" target="3z2n9okl7X57A1Ji6MO4-48" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="174" y="312" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="97" y="64" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-53" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;N&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#000000;labelBackgroundColor=none;container=0;" parent="3z2n9okl7X57A1Ji6MO4-29" vertex="1">
+          <mxGeometry x="7" y="126" width="117.03846153846153" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-54" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;V&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#000000;labelBackgroundColor=none;container=0;" parent="3z2n9okl7X57A1Ji6MO4-29" vertex="1">
+          <mxGeometry x="183.99538461538464" y="125.99704607468618" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="3z2n9okl7X57A1Ji6MO4-55" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;R&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#000000;labelBackgroundColor=none;container=0;" parent="3z2n9okl7X57A1Ji6MO4-29" vertex="1">
+          <mxGeometry x="76.00076923076927" y="126" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+  <diagram name=" V color" id="Z9s8CBdVdzPxJGSmS4Ci">
+    <mxGraphModel dx="2534" dy="542" grid="1" gridSize="1" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
+      <root>
+        <mxCell id="W413iL9ja3lEQ4Hf8mE9-0" />
+        <mxCell id="W413iL9ja3lEQ4Hf8mE9-1" parent="W413iL9ja3lEQ4Hf8mE9-0" />
+        <mxCell id="W413iL9ja3lEQ4Hf8mE9-38" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#000000;connectable=0;allowArrows=0;labelBackgroundColor=none;strokeColor=#D0CEE2;fontColor=#1A1A1A;" parent="W413iL9ja3lEQ4Hf8mE9-1" vertex="1">
+          <mxGeometry x="-286" y="562" width="510" height="448" as="geometry" />
+        </mxCell>
+        <mxCell id="W413iL9ja3lEQ4Hf8mE9-39" value="" style="rounded=0;whiteSpace=wrap;html=1;connectable=0;allowArrows=0;labelBackgroundColor=none;" parent="W413iL9ja3lEQ4Hf8mE9-1" vertex="1">
+          <mxGeometry x="-1594" y="561" width="510" height="448" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-168" value="" style="rounded=0;whiteSpace=wrap;html=1;connectable=0;allowArrows=0;labelBackgroundColor=none;fillColor=#2998dc;" parent="W413iL9ja3lEQ4Hf8mE9-1" vertex="1">
+          <mxGeometry x="-966" y="539" width="510" height="448" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-169" value="" style="group" parent="W413iL9ja3lEQ4Hf8mE9-1" vertex="1" connectable="0">
+          <mxGeometry x="-796" y="100" width="310" height="350" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-98" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=0;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-169" source="Ux6HWMlnvlPbtgL19sCr-93" target="Ux6HWMlnvlPbtgL19sCr-92" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="101" y="75" as="sourcePoint" />
+            <mxPoint x="96" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-105" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-169" source="Ux6HWMlnvlPbtgL19sCr-93" target="Ux6HWMlnvlPbtgL19sCr-92" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="110" y="265" as="sourcePoint" />
+            <mxPoint x="109" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-96" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=0.177;exitY=0.81;exitDx=0;exitDy=0;exitPerimeter=0;fontSize=19;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-169" source="Ux6HWMlnvlPbtgL19sCr-92" target="Ux6HWMlnvlPbtgL19sCr-93" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="174" y="312" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="97" y="64" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-97" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-169" target="Ux6HWMlnvlPbtgL19sCr-92" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="99" y="63" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-99" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;fontSize=19;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-169" target="Ux6HWMlnvlPbtgL19sCr-93" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="254" y="65" as="sourcePoint" />
+            <mxPoint x="169" y="93" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="209" y="68" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-100" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-169" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="210" y="69" as="sourcePoint" />
+            <mxPoint x="202" y="32" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-101" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-169" source="Ux6HWMlnvlPbtgL19sCr-94" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="157" y="89" as="sourcePoint" />
+            <mxPoint x="39" y="274" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-102" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-169" source="Ux6HWMlnvlPbtgL19sCr-95" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="73" y="134" as="sourcePoint" />
+            <mxPoint x="98" y="313" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-104" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-169" source="Ux6HWMlnvlPbtgL19sCr-103" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="161" y="139" as="sourcePoint" />
+            <mxPoint x="197" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-107" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-169" source="Ux6HWMlnvlPbtgL19sCr-106" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="263.5" y="133" as="sourcePoint" />
+            <mxPoint x="237" y="297" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-108" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-169" target="Ux6HWMlnvlPbtgL19sCr-106" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="270" y="74" as="sourcePoint" />
+            <mxPoint x="216" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-109" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-169" vertex="1">
+          <mxGeometry x="140.40499999999997" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-110" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-169" vertex="1">
+          <mxGeometry x="133.0050000000001" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-111" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-169" vertex="1">
+          <mxGeometry x="140.375" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-112" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-169" vertex="1">
+          <mxGeometry x="132.97500000000014" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-113" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-169" vertex="1">
+          <mxGeometry x="140.375" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-114" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-169" vertex="1">
+          <mxGeometry x="132.97500000000014" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-164" value="" style="group;strokeColor=none;labelBackgroundColor=none;fontColor=#0066CC;" parent="Ux6HWMlnvlPbtgL19sCr-169" vertex="1" connectable="0">
+          <mxGeometry x="7" y="125.99704607468618" width="291.28000000000003" height="120.33590785062762" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-165" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;N&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" parent="Ux6HWMlnvlPbtgL19sCr-164" vertex="1">
+          <mxGeometry y="0.0029539253138182175" width="117.03846153846153" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-166" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;V&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" parent="Ux6HWMlnvlPbtgL19sCr-164" vertex="1">
+          <mxGeometry x="176.99538461538464" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-167" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;R&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" parent="Ux6HWMlnvlPbtgL19sCr-164" vertex="1">
+          <mxGeometry x="69.00076923076927" y="0.0029539253138182175" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-94" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="Ux6HWMlnvlPbtgL19sCr-169" vertex="1">
+          <mxGeometry x="29" y="95" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-95" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="Ux6HWMlnvlPbtgL19sCr-169" vertex="1">
+          <mxGeometry x="88" y="253" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-103" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="Ux6HWMlnvlPbtgL19sCr-169" vertex="1">
+          <mxGeometry x="187" y="273" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-106" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="Ux6HWMlnvlPbtgL19sCr-169" vertex="1">
+          <mxGeometry x="227" y="87" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-93" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=6;aspect=fixed;fillColor=#7098B8;gradientDirection=radial;strokeColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#D0CEE2;" parent="Ux6HWMlnvlPbtgL19sCr-169" vertex="1">
+          <mxGeometry x="141" y="75" width="30" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-92" value="" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;size=100;rotation=90;strokeWidth=7;fillColor=none;connectable=0;strokeColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="Ux6HWMlnvlPbtgL19sCr-169" vertex="1">
+          <mxGeometry x="-20" y="20" width="350" height="310" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-198" value="" style="group" parent="W413iL9ja3lEQ4Hf8mE9-1" vertex="1" connectable="0">
+          <mxGeometry x="-865" y="595" width="310" height="350" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-199" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=0;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-198" source="Ux6HWMlnvlPbtgL19sCr-224" target="Ux6HWMlnvlPbtgL19sCr-225" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="101" y="75" as="sourcePoint" />
+            <mxPoint x="96" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-200" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-198" source="Ux6HWMlnvlPbtgL19sCr-224" target="Ux6HWMlnvlPbtgL19sCr-225" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="110" y="265" as="sourcePoint" />
+            <mxPoint x="109" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-201" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=0.177;exitY=0.81;exitDx=0;exitDy=0;exitPerimeter=0;fontSize=19;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-198" source="Ux6HWMlnvlPbtgL19sCr-225" target="Ux6HWMlnvlPbtgL19sCr-224" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="174" y="312" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="97" y="64" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-202" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-198" target="Ux6HWMlnvlPbtgL19sCr-225" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="99" y="63" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-203" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;fontSize=19;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-198" target="Ux6HWMlnvlPbtgL19sCr-224" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="254" y="65" as="sourcePoint" />
+            <mxPoint x="169" y="93" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="209" y="68" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-204" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-198" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="210" y="69" as="sourcePoint" />
+            <mxPoint x="202" y="32" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-205" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-198" source="Ux6HWMlnvlPbtgL19sCr-220" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="157" y="89" as="sourcePoint" />
+            <mxPoint x="39" y="274" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-206" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-198" source="Ux6HWMlnvlPbtgL19sCr-221" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="73" y="134" as="sourcePoint" />
+            <mxPoint x="98" y="313" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-207" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-198" source="Ux6HWMlnvlPbtgL19sCr-222" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="161" y="139" as="sourcePoint" />
+            <mxPoint x="197" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-208" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-198" source="Ux6HWMlnvlPbtgL19sCr-223" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="263.5" y="133" as="sourcePoint" />
+            <mxPoint x="237" y="297" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-209" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-198" target="Ux6HWMlnvlPbtgL19sCr-223" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="270" y="74" as="sourcePoint" />
+            <mxPoint x="216" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-210" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-198" vertex="1">
+          <mxGeometry x="140.40499999999997" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-211" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-198" vertex="1">
+          <mxGeometry x="133.0050000000001" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-212" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-198" vertex="1">
+          <mxGeometry x="140.375" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-213" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-198" vertex="1">
+          <mxGeometry x="132.97500000000014" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-214" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-198" vertex="1">
+          <mxGeometry x="140.375" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-215" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-198" vertex="1">
+          <mxGeometry x="132.97500000000014" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-216" value="" style="group;strokeColor=none;labelBackgroundColor=none;fontColor=#0066CC;" parent="Ux6HWMlnvlPbtgL19sCr-198" vertex="1" connectable="0">
+          <mxGeometry x="7" y="125.99704607468618" width="291.28000000000003" height="120.33590785062762" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-217" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;N&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" parent="Ux6HWMlnvlPbtgL19sCr-216" vertex="1">
+          <mxGeometry y="0.0029539253138182175" width="117.03846153846153" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-218" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;V&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" parent="Ux6HWMlnvlPbtgL19sCr-216" vertex="1">
+          <mxGeometry x="176.99538461538464" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-219" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;R&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" parent="Ux6HWMlnvlPbtgL19sCr-216" vertex="1">
+          <mxGeometry x="69.00076923076927" y="0.0029539253138182175" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-220" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="Ux6HWMlnvlPbtgL19sCr-198" vertex="1">
+          <mxGeometry x="29" y="95" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-221" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="Ux6HWMlnvlPbtgL19sCr-198" vertex="1">
+          <mxGeometry x="88" y="253" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-222" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="Ux6HWMlnvlPbtgL19sCr-198" vertex="1">
+          <mxGeometry x="187" y="273" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-223" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="Ux6HWMlnvlPbtgL19sCr-198" vertex="1">
+          <mxGeometry x="227" y="87" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-224" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=6;aspect=fixed;fillColor=#7098B8;gradientDirection=radial;strokeColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#D0CEE2;" parent="Ux6HWMlnvlPbtgL19sCr-198" vertex="1">
+          <mxGeometry x="141" y="75" width="30" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-225" value="" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;size=100;rotation=90;strokeWidth=7;fillColor=none;connectable=0;strokeColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="Ux6HWMlnvlPbtgL19sCr-198" vertex="1">
+          <mxGeometry x="-20" y="20" width="350" height="310" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-226" value="" style="group" parent="W413iL9ja3lEQ4Hf8mE9-1" vertex="1" connectable="0">
+          <mxGeometry x="-1541" y="620" width="310" height="350" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-227" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=0;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-226" source="Ux6HWMlnvlPbtgL19sCr-252" target="Ux6HWMlnvlPbtgL19sCr-253" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="101" y="75" as="sourcePoint" />
+            <mxPoint x="96" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-228" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-226" source="Ux6HWMlnvlPbtgL19sCr-252" target="Ux6HWMlnvlPbtgL19sCr-253" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="110" y="265" as="sourcePoint" />
+            <mxPoint x="109" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-229" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=0.177;exitY=0.81;exitDx=0;exitDy=0;exitPerimeter=0;fontSize=19;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-226" source="Ux6HWMlnvlPbtgL19sCr-253" target="Ux6HWMlnvlPbtgL19sCr-252" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="174" y="312" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="97" y="64" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-230" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-226" target="Ux6HWMlnvlPbtgL19sCr-253" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="99" y="63" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-231" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;fontSize=19;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-226" target="Ux6HWMlnvlPbtgL19sCr-252" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="254" y="65" as="sourcePoint" />
+            <mxPoint x="169" y="93" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="209" y="68" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-232" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-226" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="210" y="69" as="sourcePoint" />
+            <mxPoint x="202" y="32" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-233" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-226" source="Ux6HWMlnvlPbtgL19sCr-248" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="157" y="89" as="sourcePoint" />
+            <mxPoint x="39" y="274" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-234" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-226" source="Ux6HWMlnvlPbtgL19sCr-249" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="73" y="134" as="sourcePoint" />
+            <mxPoint x="98" y="313" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-235" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-226" source="Ux6HWMlnvlPbtgL19sCr-250" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="161" y="139" as="sourcePoint" />
+            <mxPoint x="197" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-236" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-226" source="Ux6HWMlnvlPbtgL19sCr-251" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="263.5" y="133" as="sourcePoint" />
+            <mxPoint x="237" y="297" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-237" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-226" target="Ux6HWMlnvlPbtgL19sCr-251" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="270" y="74" as="sourcePoint" />
+            <mxPoint x="216" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-238" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-226" vertex="1">
+          <mxGeometry x="140.40499999999997" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-239" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-226" vertex="1">
+          <mxGeometry x="133.0050000000001" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-240" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-226" vertex="1">
+          <mxGeometry x="140.375" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-241" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-226" vertex="1">
+          <mxGeometry x="132.97500000000014" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-242" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-226" vertex="1">
+          <mxGeometry x="140.375" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-243" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-226" vertex="1">
+          <mxGeometry x="132.97500000000014" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-244" value="" style="group;strokeColor=none;labelBackgroundColor=none;fontColor=#0066CC;" parent="Ux6HWMlnvlPbtgL19sCr-226" vertex="1" connectable="0">
+          <mxGeometry x="7" y="125.99704607468618" width="291.28000000000003" height="120.33590785062762" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-245" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;N&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" parent="Ux6HWMlnvlPbtgL19sCr-244" vertex="1">
+          <mxGeometry y="0.0029539253138182175" width="117.03846153846153" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-246" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;V&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" parent="Ux6HWMlnvlPbtgL19sCr-244" vertex="1">
+          <mxGeometry x="176.99538461538464" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-247" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;R&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" parent="Ux6HWMlnvlPbtgL19sCr-244" vertex="1">
+          <mxGeometry x="69.00076923076927" y="0.0029539253138182175" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-248" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="Ux6HWMlnvlPbtgL19sCr-226" vertex="1">
+          <mxGeometry x="29" y="95" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-249" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="Ux6HWMlnvlPbtgL19sCr-226" vertex="1">
+          <mxGeometry x="88" y="253" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-250" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="Ux6HWMlnvlPbtgL19sCr-226" vertex="1">
+          <mxGeometry x="187" y="273" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-251" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="Ux6HWMlnvlPbtgL19sCr-226" vertex="1">
+          <mxGeometry x="227" y="87" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-252" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=6;aspect=fixed;fillColor=#7098B8;gradientDirection=radial;strokeColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#D0CEE2;" parent="Ux6HWMlnvlPbtgL19sCr-226" vertex="1">
+          <mxGeometry x="141" y="75" width="30" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-253" value="" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;size=100;rotation=90;strokeWidth=7;fillColor=none;connectable=0;strokeColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="Ux6HWMlnvlPbtgL19sCr-226" vertex="1">
+          <mxGeometry x="-20" y="20" width="350" height="310" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-254" value="" style="group" parent="W413iL9ja3lEQ4Hf8mE9-1" vertex="1" connectable="0">
+          <mxGeometry x="-183" y="618" width="310" height="350" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-255" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=0;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-254" source="Ux6HWMlnvlPbtgL19sCr-280" target="Ux6HWMlnvlPbtgL19sCr-281" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="101" y="75" as="sourcePoint" />
+            <mxPoint x="96" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-256" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-254" source="Ux6HWMlnvlPbtgL19sCr-280" target="Ux6HWMlnvlPbtgL19sCr-281" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="110" y="265" as="sourcePoint" />
+            <mxPoint x="109" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-257" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=0.177;exitY=0.81;exitDx=0;exitDy=0;exitPerimeter=0;fontSize=19;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-254" source="Ux6HWMlnvlPbtgL19sCr-281" target="Ux6HWMlnvlPbtgL19sCr-280" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="174" y="312" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="97" y="64" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-258" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-254" target="Ux6HWMlnvlPbtgL19sCr-281" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="99" y="63" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-259" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;fontSize=19;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-254" target="Ux6HWMlnvlPbtgL19sCr-280" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="254" y="65" as="sourcePoint" />
+            <mxPoint x="169" y="93" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="209" y="68" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-260" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-254" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="210" y="69" as="sourcePoint" />
+            <mxPoint x="202" y="32" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-261" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-254" source="Ux6HWMlnvlPbtgL19sCr-276" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="157" y="89" as="sourcePoint" />
+            <mxPoint x="39" y="274" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-262" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-254" source="Ux6HWMlnvlPbtgL19sCr-277" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="73" y="134" as="sourcePoint" />
+            <mxPoint x="98" y="313" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-263" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-254" source="Ux6HWMlnvlPbtgL19sCr-278" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="161" y="139" as="sourcePoint" />
+            <mxPoint x="197" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-264" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-254" source="Ux6HWMlnvlPbtgL19sCr-279" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="263.5" y="133" as="sourcePoint" />
+            <mxPoint x="237" y="297" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-265" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="Ux6HWMlnvlPbtgL19sCr-254" target="Ux6HWMlnvlPbtgL19sCr-279" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="270" y="74" as="sourcePoint" />
+            <mxPoint x="216" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-266" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-254" vertex="1">
+          <mxGeometry x="140.40499999999997" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-267" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-254" vertex="1">
+          <mxGeometry x="133.0050000000001" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-268" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-254" vertex="1">
+          <mxGeometry x="140.375" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-269" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-254" vertex="1">
+          <mxGeometry x="132.97500000000014" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-270" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-254" vertex="1">
+          <mxGeometry x="140.375" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-271" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="Ux6HWMlnvlPbtgL19sCr-254" vertex="1">
+          <mxGeometry x="132.97500000000014" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-272" value="" style="group;strokeColor=none;labelBackgroundColor=none;fontColor=#0066CC;" parent="Ux6HWMlnvlPbtgL19sCr-254" vertex="1" connectable="0">
+          <mxGeometry x="7" y="125.99704607468618" width="291.28000000000003" height="120.33590785062762" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-273" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;N&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" parent="Ux6HWMlnvlPbtgL19sCr-272" vertex="1">
+          <mxGeometry y="0.0029539253138182175" width="117.03846153846153" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-274" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;V&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" parent="Ux6HWMlnvlPbtgL19sCr-272" vertex="1">
+          <mxGeometry x="176.99538461538464" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-275" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;R&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" parent="Ux6HWMlnvlPbtgL19sCr-272" vertex="1">
+          <mxGeometry x="69.00076923076927" y="0.0029539253138182175" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-276" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="Ux6HWMlnvlPbtgL19sCr-254" vertex="1">
+          <mxGeometry x="29" y="95" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-277" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="Ux6HWMlnvlPbtgL19sCr-254" vertex="1">
+          <mxGeometry x="88" y="253" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-278" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="Ux6HWMlnvlPbtgL19sCr-254" vertex="1">
+          <mxGeometry x="187" y="273" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-279" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="Ux6HWMlnvlPbtgL19sCr-254" vertex="1">
+          <mxGeometry x="227" y="87" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-280" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=6;aspect=fixed;fillColor=#7098B8;gradientDirection=radial;strokeColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#D0CEE2;" parent="Ux6HWMlnvlPbtgL19sCr-254" vertex="1">
+          <mxGeometry x="141" y="75" width="30" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="Ux6HWMlnvlPbtgL19sCr-281" value="" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;size=100;rotation=90;strokeWidth=7;fillColor=none;connectable=0;strokeColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="Ux6HWMlnvlPbtgL19sCr-254" vertex="1">
+          <mxGeometry x="-20" y="20" width="350" height="310" as="geometry" />
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+  <diagram name="V square" id="3_SILxOyEmDKBxAtW-k4">
+    <mxGraphModel dx="2534" dy="542" grid="1" gridSize="1" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
+      <root>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-0" />
+        <mxCell id="w-hIV7pQSxMcubldxXHa-1" parent="w-hIV7pQSxMcubldxXHa-0" />
+        <mxCell id="w-hIV7pQSxMcubldxXHa-2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#000000;connectable=0;allowArrows=0;labelBackgroundColor=none;strokeColor=#D0CEE2;fontColor=#1A1A1A;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-1">
+          <mxGeometry x="-286" y="562" width="510" height="448" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-3" value="" style="rounded=0;whiteSpace=wrap;html=1;connectable=0;allowArrows=0;labelBackgroundColor=none;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-1">
+          <mxGeometry x="-1594" y="561" width="510" height="448" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-4" value="" style="rounded=0;whiteSpace=wrap;html=1;connectable=0;allowArrows=0;labelBackgroundColor=none;fillColor=#2998dc;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-1">
+          <mxGeometry x="-966" y="539" width="510" height="448" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-5" value="" style="group" vertex="1" connectable="0" parent="w-hIV7pQSxMcubldxXHa-1">
+          <mxGeometry x="-796" y="100" width="339" height="358" as="geometry" />
+        </mxCell>
+        <mxCell id="cid_LdfjpjZIyp-2fD9l-1" value="" style="whiteSpace=wrap;html=1;aspect=fixed;fillColor=none;strokeColor=none;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-5">
+          <mxGeometry x="-27" y="-8" width="366" height="366" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-6" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=0;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-5" source="w-hIV7pQSxMcubldxXHa-31" target="w-hIV7pQSxMcubldxXHa-32">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="101" y="75" as="sourcePoint" />
+            <mxPoint x="96" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-7" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-5" source="w-hIV7pQSxMcubldxXHa-31" target="w-hIV7pQSxMcubldxXHa-32">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="110" y="265" as="sourcePoint" />
+            <mxPoint x="109" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-8" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=0.177;exitY=0.81;exitDx=0;exitDy=0;exitPerimeter=0;fontSize=19;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-5" source="w-hIV7pQSxMcubldxXHa-32" target="w-hIV7pQSxMcubldxXHa-31">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="174" y="312" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="97" y="64" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-9" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-5" target="w-hIV7pQSxMcubldxXHa-32">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="99" y="63" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-10" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;fontSize=19;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-5" target="w-hIV7pQSxMcubldxXHa-31">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="254" y="65" as="sourcePoint" />
+            <mxPoint x="169" y="93" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="209" y="68" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-11" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-5">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="210" y="69" as="sourcePoint" />
+            <mxPoint x="202" y="32" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-12" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-5" source="w-hIV7pQSxMcubldxXHa-27">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="157" y="89" as="sourcePoint" />
+            <mxPoint x="39" y="274" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-13" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-5" source="w-hIV7pQSxMcubldxXHa-28">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="73" y="134" as="sourcePoint" />
+            <mxPoint x="98" y="313" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-14" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-5" source="w-hIV7pQSxMcubldxXHa-29">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="161" y="139" as="sourcePoint" />
+            <mxPoint x="197" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-15" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-5" source="w-hIV7pQSxMcubldxXHa-30">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="263.5" y="133" as="sourcePoint" />
+            <mxPoint x="237" y="297" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-16" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-5" target="w-hIV7pQSxMcubldxXHa-30">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="270" y="74" as="sourcePoint" />
+            <mxPoint x="216" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-17" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-5">
+          <mxGeometry x="140.40499999999997" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-18" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-5">
+          <mxGeometry x="133.0050000000001" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-19" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-5">
+          <mxGeometry x="140.375" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-20" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-5">
+          <mxGeometry x="132.97500000000014" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-21" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-5">
+          <mxGeometry x="140.375" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-22" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-5">
+          <mxGeometry x="132.97500000000014" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-23" value="" style="group;strokeColor=none;labelBackgroundColor=none;fontColor=#0066CC;" vertex="1" connectable="0" parent="w-hIV7pQSxMcubldxXHa-5">
+          <mxGeometry x="7" y="125.99704607468618" width="291.28000000000003" height="120.33590785062762" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-24" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;N&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-23">
+          <mxGeometry y="0.0029539253138182175" width="117.03846153846153" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-25" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;V&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-23">
+          <mxGeometry x="176.99538461538464" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-26" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;R&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-23">
+          <mxGeometry x="69.00076923076927" y="0.0029539253138182175" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-27" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-5">
+          <mxGeometry x="29" y="95" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-28" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-5">
+          <mxGeometry x="88" y="253" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-29" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-5">
+          <mxGeometry x="187" y="273" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-30" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-5">
+          <mxGeometry x="227" y="87" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-31" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=6;aspect=fixed;fillColor=#7098B8;gradientDirection=radial;strokeColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#D0CEE2;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-5">
+          <mxGeometry x="141" y="75" width="30" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-32" value="" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;size=100;rotation=90;strokeWidth=7;fillColor=none;connectable=0;strokeColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-5">
+          <mxGeometry x="-20" y="20" width="350" height="310" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-33" value="" style="group" vertex="1" connectable="0" parent="w-hIV7pQSxMcubldxXHa-1">
+          <mxGeometry x="-865" y="595" width="310" height="350" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-34" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=0;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-33" source="w-hIV7pQSxMcubldxXHa-59" target="w-hIV7pQSxMcubldxXHa-60">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="101" y="75" as="sourcePoint" />
+            <mxPoint x="96" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-35" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-33" source="w-hIV7pQSxMcubldxXHa-59" target="w-hIV7pQSxMcubldxXHa-60">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="110" y="265" as="sourcePoint" />
+            <mxPoint x="109" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-36" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=0.177;exitY=0.81;exitDx=0;exitDy=0;exitPerimeter=0;fontSize=19;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-33" source="w-hIV7pQSxMcubldxXHa-60" target="w-hIV7pQSxMcubldxXHa-59">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="174" y="312" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="97" y="64" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-37" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-33" target="w-hIV7pQSxMcubldxXHa-60">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="99" y="63" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-38" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;fontSize=19;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-33" target="w-hIV7pQSxMcubldxXHa-59">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="254" y="65" as="sourcePoint" />
+            <mxPoint x="169" y="93" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="209" y="68" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-39" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-33">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="210" y="69" as="sourcePoint" />
+            <mxPoint x="202" y="32" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-40" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-33" source="w-hIV7pQSxMcubldxXHa-55">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="157" y="89" as="sourcePoint" />
+            <mxPoint x="39" y="274" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-41" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-33" source="w-hIV7pQSxMcubldxXHa-56">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="73" y="134" as="sourcePoint" />
+            <mxPoint x="98" y="313" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-42" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-33" source="w-hIV7pQSxMcubldxXHa-57">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="161" y="139" as="sourcePoint" />
+            <mxPoint x="197" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-43" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-33" source="w-hIV7pQSxMcubldxXHa-58">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="263.5" y="133" as="sourcePoint" />
+            <mxPoint x="237" y="297" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-44" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-33" target="w-hIV7pQSxMcubldxXHa-58">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="270" y="74" as="sourcePoint" />
+            <mxPoint x="216" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-45" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-33">
+          <mxGeometry x="140.40499999999997" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-46" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-33">
+          <mxGeometry x="133.0050000000001" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-47" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-33">
+          <mxGeometry x="140.375" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-48" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-33">
+          <mxGeometry x="132.97500000000014" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-49" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-33">
+          <mxGeometry x="140.375" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-50" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-33">
+          <mxGeometry x="132.97500000000014" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-51" value="" style="group;strokeColor=none;labelBackgroundColor=none;fontColor=#0066CC;" vertex="1" connectable="0" parent="w-hIV7pQSxMcubldxXHa-33">
+          <mxGeometry x="7" y="125.99704607468618" width="291.28000000000003" height="120.33590785062762" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-52" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;N&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-51">
+          <mxGeometry y="0.0029539253138182175" width="117.03846153846153" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-53" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;V&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-51">
+          <mxGeometry x="176.99538461538464" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-54" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;R&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-51">
+          <mxGeometry x="69.00076923076927" y="0.0029539253138182175" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-55" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-33">
+          <mxGeometry x="29" y="95" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-56" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-33">
+          <mxGeometry x="88" y="253" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-57" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-33">
+          <mxGeometry x="187" y="273" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-58" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-33">
+          <mxGeometry x="227" y="87" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-59" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=6;aspect=fixed;fillColor=#7098B8;gradientDirection=radial;strokeColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#D0CEE2;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-33">
+          <mxGeometry x="141" y="75" width="30" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-60" value="" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;size=100;rotation=90;strokeWidth=7;fillColor=none;connectable=0;strokeColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-33">
+          <mxGeometry x="-20" y="20" width="350" height="310" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-61" value="" style="group" vertex="1" connectable="0" parent="w-hIV7pQSxMcubldxXHa-1">
+          <mxGeometry x="-1541" y="620" width="310" height="350" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-62" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=0;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-61" source="w-hIV7pQSxMcubldxXHa-87" target="w-hIV7pQSxMcubldxXHa-88">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="101" y="75" as="sourcePoint" />
+            <mxPoint x="96" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-63" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-61" source="w-hIV7pQSxMcubldxXHa-87" target="w-hIV7pQSxMcubldxXHa-88">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="110" y="265" as="sourcePoint" />
+            <mxPoint x="109" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-64" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=0.177;exitY=0.81;exitDx=0;exitDy=0;exitPerimeter=0;fontSize=19;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-61" source="w-hIV7pQSxMcubldxXHa-88" target="w-hIV7pQSxMcubldxXHa-87">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="174" y="312" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="97" y="64" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-65" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-61" target="w-hIV7pQSxMcubldxXHa-88">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="99" y="63" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-66" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;fontSize=19;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-61" target="w-hIV7pQSxMcubldxXHa-87">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="254" y="65" as="sourcePoint" />
+            <mxPoint x="169" y="93" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="209" y="68" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-67" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-61">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="210" y="69" as="sourcePoint" />
+            <mxPoint x="202" y="32" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-68" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-61" source="w-hIV7pQSxMcubldxXHa-83">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="157" y="89" as="sourcePoint" />
+            <mxPoint x="39" y="274" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-69" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-61" source="w-hIV7pQSxMcubldxXHa-84">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="73" y="134" as="sourcePoint" />
+            <mxPoint x="98" y="313" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-70" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-61" source="w-hIV7pQSxMcubldxXHa-85">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="161" y="139" as="sourcePoint" />
+            <mxPoint x="197" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-71" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-61" source="w-hIV7pQSxMcubldxXHa-86">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="263.5" y="133" as="sourcePoint" />
+            <mxPoint x="237" y="297" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-72" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-61" target="w-hIV7pQSxMcubldxXHa-86">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="270" y="74" as="sourcePoint" />
+            <mxPoint x="216" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-73" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-61">
+          <mxGeometry x="140.40499999999997" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-74" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-61">
+          <mxGeometry x="133.0050000000001" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-75" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-61">
+          <mxGeometry x="140.375" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-76" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-61">
+          <mxGeometry x="132.97500000000014" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-77" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-61">
+          <mxGeometry x="140.375" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-78" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-61">
+          <mxGeometry x="132.97500000000014" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-79" value="" style="group;strokeColor=none;labelBackgroundColor=none;fontColor=#0066CC;" vertex="1" connectable="0" parent="w-hIV7pQSxMcubldxXHa-61">
+          <mxGeometry x="7" y="125.99704607468618" width="291.28000000000003" height="120.33590785062762" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-80" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;N&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-79">
+          <mxGeometry y="0.0029539253138182175" width="117.03846153846153" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-81" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;V&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-79">
+          <mxGeometry x="176.99538461538464" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-82" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;R&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-79">
+          <mxGeometry x="69.00076923076927" y="0.0029539253138182175" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-83" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-61">
+          <mxGeometry x="29" y="95" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-84" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-61">
+          <mxGeometry x="88" y="253" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-85" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-61">
+          <mxGeometry x="187" y="273" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-86" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-61">
+          <mxGeometry x="227" y="87" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-87" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=6;aspect=fixed;fillColor=#7098B8;gradientDirection=radial;strokeColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#D0CEE2;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-61">
+          <mxGeometry x="141" y="75" width="30" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-88" value="" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;size=100;rotation=90;strokeWidth=7;fillColor=none;connectable=0;strokeColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-61">
+          <mxGeometry x="-20" y="20" width="350" height="310" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-89" value="" style="group" vertex="1" connectable="0" parent="w-hIV7pQSxMcubldxXHa-1">
+          <mxGeometry x="-183" y="618" width="310" height="350" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-90" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=0;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-89" source="w-hIV7pQSxMcubldxXHa-115" target="w-hIV7pQSxMcubldxXHa-116">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="101" y="75" as="sourcePoint" />
+            <mxPoint x="96" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-91" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-89" source="w-hIV7pQSxMcubldxXHa-115" target="w-hIV7pQSxMcubldxXHa-116">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="110" y="265" as="sourcePoint" />
+            <mxPoint x="109" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-92" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=0.177;exitY=0.81;exitDx=0;exitDy=0;exitPerimeter=0;fontSize=19;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-89" source="w-hIV7pQSxMcubldxXHa-116" target="w-hIV7pQSxMcubldxXHa-115">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="174" y="312" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="97" y="64" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-93" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-89" target="w-hIV7pQSxMcubldxXHa-116">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="99" y="63" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-94" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;fontSize=19;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-89" target="w-hIV7pQSxMcubldxXHa-115">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="254" y="65" as="sourcePoint" />
+            <mxPoint x="169" y="93" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="209" y="68" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-95" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-89">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="210" y="69" as="sourcePoint" />
+            <mxPoint x="202" y="32" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-96" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-89" source="w-hIV7pQSxMcubldxXHa-111">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="157" y="89" as="sourcePoint" />
+            <mxPoint x="39" y="274" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-97" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-89" source="w-hIV7pQSxMcubldxXHa-112">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="73" y="134" as="sourcePoint" />
+            <mxPoint x="98" y="313" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-98" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-89" source="w-hIV7pQSxMcubldxXHa-113">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="161" y="139" as="sourcePoint" />
+            <mxPoint x="197" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-99" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-89" source="w-hIV7pQSxMcubldxXHa-114">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="263.5" y="133" as="sourcePoint" />
+            <mxPoint x="237" y="297" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-100" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" edge="1" parent="w-hIV7pQSxMcubldxXHa-89" target="w-hIV7pQSxMcubldxXHa-114">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="270" y="74" as="sourcePoint" />
+            <mxPoint x="216" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-101" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-89">
+          <mxGeometry x="140.40499999999997" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-102" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-89">
+          <mxGeometry x="133.0050000000001" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-103" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-89">
+          <mxGeometry x="140.375" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-104" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-89">
+          <mxGeometry x="132.97500000000014" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-105" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-89">
+          <mxGeometry x="140.375" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-106" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-89">
+          <mxGeometry x="132.97500000000014" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-107" value="" style="group;strokeColor=none;labelBackgroundColor=none;fontColor=#0066CC;" vertex="1" connectable="0" parent="w-hIV7pQSxMcubldxXHa-89">
+          <mxGeometry x="7" y="125.99704607468618" width="291.28000000000003" height="120.33590785062762" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-108" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;N&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-107">
+          <mxGeometry y="0.0029539253138182175" width="117.03846153846153" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-109" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;V&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-107">
+          <mxGeometry x="176.99538461538464" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-110" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;R&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-107">
+          <mxGeometry x="69.00076923076927" y="0.0029539253138182175" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-111" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-89">
+          <mxGeometry x="29" y="95" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-112" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-89">
+          <mxGeometry x="88" y="253" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-113" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-89">
+          <mxGeometry x="187" y="273" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-114" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-89">
+          <mxGeometry x="227" y="87" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-115" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=6;aspect=fixed;fillColor=#7098B8;gradientDirection=radial;strokeColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#D0CEE2;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-89">
+          <mxGeometry x="141" y="75" width="30" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="w-hIV7pQSxMcubldxXHa-116" value="" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;size=100;rotation=90;strokeWidth=7;fillColor=none;connectable=0;strokeColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" vertex="1" parent="w-hIV7pQSxMcubldxXHa-89">
+          <mxGeometry x="-20" y="20" width="350" height="310" as="geometry" />
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+  <diagram name="Copy of  V color" id="VTgzHfinKLVhWrpzoLbt">
+    <mxGraphModel dx="2181" dy="834" grid="1" gridSize="1" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
+      <root>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-0" />
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-1" parent="K9QRx28HvHQRM9BmkFQ0-0" />
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-5" value="" style="group" parent="K9QRx28HvHQRM9BmkFQ0-1" vertex="1" connectable="0">
+          <mxGeometry x="-796" y="100" width="310" height="350" as="geometry" />
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-6" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=0;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="K9QRx28HvHQRM9BmkFQ0-5" source="K9QRx28HvHQRM9BmkFQ0-31" target="K9QRx28HvHQRM9BmkFQ0-32" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="101" y="75" as="sourcePoint" />
+            <mxPoint x="96" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-7" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="K9QRx28HvHQRM9BmkFQ0-5" source="K9QRx28HvHQRM9BmkFQ0-31" target="K9QRx28HvHQRM9BmkFQ0-32" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="110" y="265" as="sourcePoint" />
+            <mxPoint x="109" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-8" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=0.177;exitY=0.81;exitDx=0;exitDy=0;exitPerimeter=0;fontSize=19;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="K9QRx28HvHQRM9BmkFQ0-5" source="K9QRx28HvHQRM9BmkFQ0-32" target="K9QRx28HvHQRM9BmkFQ0-31" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="174" y="312" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="97" y="64" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-9" value="" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="K9QRx28HvHQRM9BmkFQ0-5" target="K9QRx28HvHQRM9BmkFQ0-32" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="99" y="63" as="sourcePoint" />
+            <mxPoint x="224" y="262" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-10" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;fontSize=19;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="K9QRx28HvHQRM9BmkFQ0-5" target="K9QRx28HvHQRM9BmkFQ0-31" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="254" y="65" as="sourcePoint" />
+            <mxPoint x="169" y="93" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="209" y="68" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-11" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="K9QRx28HvHQRM9BmkFQ0-5" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="210" y="69" as="sourcePoint" />
+            <mxPoint x="202" y="32" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-12" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="K9QRx28HvHQRM9BmkFQ0-5" source="K9QRx28HvHQRM9BmkFQ0-27" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="157" y="89" as="sourcePoint" />
+            <mxPoint x="39" y="274" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-13" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="K9QRx28HvHQRM9BmkFQ0-5" source="K9QRx28HvHQRM9BmkFQ0-28" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="73" y="134" as="sourcePoint" />
+            <mxPoint x="98" y="313" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-14" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1.088;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="K9QRx28HvHQRM9BmkFQ0-5" source="K9QRx28HvHQRM9BmkFQ0-29" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="161" y="139" as="sourcePoint" />
+            <mxPoint x="197" y="323" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-15" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=6;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="K9QRx28HvHQRM9BmkFQ0-5" source="K9QRx28HvHQRM9BmkFQ0-30" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="263.5" y="133" as="sourcePoint" />
+            <mxPoint x="237" y="297" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-16" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;strokeWidth=6;strokeColor=#736CA8;labelBackgroundColor=none;fontColor=default;" parent="K9QRx28HvHQRM9BmkFQ0-5" target="K9QRx28HvHQRM9BmkFQ0-30" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="270" y="74" as="sourcePoint" />
+            <mxPoint x="216" y="40" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-17" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="K9QRx28HvHQRM9BmkFQ0-5" vertex="1">
+          <mxGeometry x="140.40499999999997" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-18" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="K9QRx28HvHQRM9BmkFQ0-5" vertex="1">
+          <mxGeometry x="133.0050000000001" y="317.895" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-19" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="K9QRx28HvHQRM9BmkFQ0-5" vertex="1">
+          <mxGeometry x="140.375" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-20" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="K9QRx28HvHQRM9BmkFQ0-5" vertex="1">
+          <mxGeometry x="132.97500000000014" y="273.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-21" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=north;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="K9QRx28HvHQRM9BmkFQ0-5" vertex="1">
+          <mxGeometry x="140.375" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-22" value="" style="rounded=1;whiteSpace=wrap;html=1;rotation=90;fillColor=#736CA8;strokeColor=none;gradientDirection=south;arcSize=41;container=0;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#5D7F99;" parent="K9QRx28HvHQRM9BmkFQ0-5" vertex="1">
+          <mxGeometry x="132.97500000000014" y="229.015" width="36.62" height="8.58" as="geometry" />
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-23" value="" style="group;strokeColor=none;labelBackgroundColor=none;fontColor=#0066CC;" parent="K9QRx28HvHQRM9BmkFQ0-5" vertex="1" connectable="0">
+          <mxGeometry x="7" y="125.99704607468618" width="291.28000000000003" height="120.33590785062762" as="geometry" />
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-24" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;N&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" parent="K9QRx28HvHQRM9BmkFQ0-23" vertex="1">
+          <mxGeometry y="0.0029539253138182175" width="117.03846153846153" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-25" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;V&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" parent="K9QRx28HvHQRM9BmkFQ0-23" vertex="1">
+          <mxGeometry x="176.99538461538464" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-26" value="&lt;font style=&quot;font-size: 180px;&quot;&gt;R&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=Archive;fontSize=180;connectable=0;allowArrows=0;fontColor=#004C99;labelBackgroundColor=none;" parent="K9QRx28HvHQRM9BmkFQ0-23" vertex="1">
+          <mxGeometry x="69.00076923076927" y="0.0029539253138182175" width="114.28461538461538" height="120.33295392531379" as="geometry" />
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-27" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="K9QRx28HvHQRM9BmkFQ0-5" vertex="1">
+          <mxGeometry x="29" y="95" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-28" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="K9QRx28HvHQRM9BmkFQ0-5" vertex="1">
+          <mxGeometry x="88" y="253" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-29" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="K9QRx28HvHQRM9BmkFQ0-5" vertex="1">
+          <mxGeometry x="187" y="273" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-30" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=7;aspect=fixed;strokeColor=#D0CEE2;fillColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="K9QRx28HvHQRM9BmkFQ0-5" vertex="1">
+          <mxGeometry x="227" y="87" width="20" height="20" as="geometry" />
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-31" value="" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=6;aspect=fixed;fillColor=#7098B8;gradientDirection=radial;strokeColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;gradientColor=#D0CEE2;" parent="K9QRx28HvHQRM9BmkFQ0-5" vertex="1">
+          <mxGeometry x="141" y="75" width="30" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="K9QRx28HvHQRM9BmkFQ0-32" value="" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;size=100;rotation=90;strokeWidth=7;fillColor=none;connectable=0;strokeColor=#D0CEE2;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="K9QRx28HvHQRM9BmkFQ0-5" vertex="1">
+          <mxGeometry x="-20" y="20" width="350" height="310" as="geometry" />
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+  <diagram id="PPPYtLvpt0ZroRAuMfQf" name="Page-4">
+    <mxGraphModel dx="880" dy="542" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
+      <root>
+        <mxCell id="0" />
+        <mxCell id="1" parent="0" />
+        <mxCell id="6vAsQUhHoDgJptBfU-dv-1" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;strokeColor=#325ce8;strokeWidth=7;" parent="1" vertex="1">
+          <mxGeometry x="400" y="299.99999999999994" width="20.729491525423732" height="20.729491525423732" as="geometry" />
+        </mxCell>
+        <mxCell id="6vAsQUhHoDgJptBfU-dv-2" value="" style="html=1;verticalLabelPosition=bottom;align=center;labelBackgroundColor=#ffffff;verticalAlign=top;strokeWidth=0.5;strokeColor=#FFFFFF;shadow=0;dashed=0;shape=mxgraph.ios7.icons.chat;fillColor=#325CE8;" parent="1" vertex="1">
+          <mxGeometry x="403.02058305084745" y="306.3965288135593" width="14.747552542372885" height="9.397369491525424" as="geometry" />
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+</mxfile>
diff --git a/docs/__logo/logo.png b/docs/__logo/logo.png
new file mode 100644
index 00000000..c7b69df4
Binary files /dev/null and b/docs/__logo/logo.png differ
diff --git a/docs/_templates/autosummary/base.rst b/docs/_templates/autosummary/base.rst
new file mode 100644
index 00000000..e03319b8
--- /dev/null
+++ b/docs/_templates/autosummary/base.rst
@@ -0,0 +1,5 @@
+{{ objname | escape | underline}}
+
+.. currentmodule:: {{ module }}
+
+.. auto{{ objtype }}:: {{ objname }}
diff --git a/docs/_templates/autosummary/class.rst b/docs/_templates/autosummary/class.rst
new file mode 100644
index 00000000..6500108f
--- /dev/null
+++ b/docs/_templates/autosummary/class.rst
@@ -0,0 +1,30 @@
+{{ objname | escape | underline}}
+
+.. currentmodule:: {{ module }}
+
+.. autoclass:: {{ objname }}
+
+{% block attributes %}
+{% if attributes %}
+Attributes
+----------
+.. autosummary::
+    :toctree: {{ name }}
+{% for item in attributes %}
+    {{ name }}.{{ item }}
+{% endfor %}
+{% endif %}
+{% endblock %}
+
+{% block methods %}
+{% if methods %}
+Methods
+-------
+.. autosummary::
+    :toctree: {{ name }}
+    
+{% for item in methods %}
+    {{ name }}.{{ item }}
+{% endfor %}
+{% endif %}
+{% endblock %}
diff --git a/docs/_templates/autosummary/module.rst b/docs/_templates/autosummary/module.rst
new file mode 100644
index 00000000..f2f379f2
--- /dev/null
+++ b/docs/_templates/autosummary/module.rst
@@ -0,0 +1,41 @@
+{{ fullname | escape | underline }}
+
+Description
+-----------
+.. automodule:: {{ fullname }}
+.. currentmodule:: {{ fullname }}
+
+
+{% if modules %}
+Subpackages
+-----------
+.. autosummary::
+    :toctree: {{ name }}
+    :recursive:
+    {% for module in modules %}
+    {{ module }}
+    {% endfor %}
+{% endif %}
+
+
+
+{% if classes %}
+Classes
+-------
+.. autosummary::
+    :toctree: {{ name }}
+    {% for class in classes %}
+    {{ class }}
+    {% endfor %}
+{% endif %}
+
+{% if functions %}
+Functions
+---------
+
+.. autosummary:: 
+    :toctree: {{ name }}
+    {% for function in functions %}
+    {{ function }}
+    {% endfor %}
+{% endif %}
diff --git a/docs/conf.py b/docs/conf.py
index 9e40d4fd..b1a7d906 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -94,12 +94,12 @@
 ]
 
 templates_path = ["_templates"]
-exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "examples/__nodoc"]
+exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "examples/__nodoc", "__logo/__build"]
 
 # -- Options for HTML output -------------------------------------------------
 # Web site
 html_title = f"{project} {version}"  # document title
-html_logo = "images/logo.png"  # project logo
+html_logo = "__logo/logo.png"  # project logo
 
 # Rendering options
 myst_heading_anchors = 2  # Generate link anchors for sections.
@@ -119,3 +119,5 @@
 autodoc_member_order = 'bysource' # keep the order of class and function source files
 #                                   (thus don't use alphabetical order)
 autosummary_generate = True
+
+autosummary_ignore_module_all = False
\ No newline at end of file
diff --git a/docs/devcorner.rst b/docs/devcorner.rst
index d1748148..ba1eb899 100644
--- a/docs/devcorner.rst
+++ b/docs/devcorner.rst
@@ -176,6 +176,9 @@ All code sources for the unitary tests can be found in the *tests/unitary_tests/
     *   - 500
         - 509
         - Various functions
+    *   - 900
+        - 950
+        - Machine and autoconfig
 
 
 Public roadmap
diff --git a/docs/images/logo.png b/docs/images/logo.png
deleted file mode 100644
index 80522391..00000000
Binary files a/docs/images/logo.png and /dev/null differ
diff --git a/docs/modules.rst b/docs/modules.rst
index a35f69e9..8dc4eb06 100644
--- a/docs/modules.rst
+++ b/docs/modules.rst
@@ -1,9 +1,29 @@
 .. _modules:
 
-API documentation
-=================
+API Reference
+=============
 
-.. toctree::
-   :maxdepth: 5
 
-   nrv/nrv
+Module contents
+---------------
+
+.. automodule:: nrv
+   :members:
+   :undoc-members:
+   :show-inheritance:
+   :exclude-members: DummyClass
+
+Subpackages
+-----------
+
+.. autosummary::
+   :toctree: _nrv
+   :recursive:
+
+   nmod
+   fmod
+   optim
+   eit
+   utils
+   ui
+   backend
diff --git a/docs/nrv/backend/mod_10_compileMods.rst b/docs/nrv/backend/mod_10_compileMods.rst
deleted file mode 100644
index b23c4a03..00000000
--- a/docs/nrv/backend/mod_10_compileMods.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.backend.compileMods module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.backend.compileMods
-   :members:
-   :undoc-members:
-   :show-inheritance:
diff --git a/docs/nrv/backend/mod_11_wrappers.rst b/docs/nrv/backend/mod_11_wrappers.rst
deleted file mode 100644
index 60006e1f..00000000
--- a/docs/nrv/backend/mod_11_wrappers.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.backend.wrappers module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.backend.wrappers
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/backend/mod_1_NRV_Class.rst b/docs/nrv/backend/mod_1_NRV_Class.rst
deleted file mode 100644
index 4f6d8d4e..00000000
--- a/docs/nrv/backend/mod_1_NRV_Class.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.backend.NRV\_Class module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.backend.NRV_Class
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/backend/mod_2_NRV_Simulable.rst b/docs/nrv/backend/mod_2_NRV_Simulable.rst
deleted file mode 100644
index a3b55fae..00000000
--- a/docs/nrv/backend/mod_2_NRV_Simulable.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.backend.NRV\_Simulable module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.backend.NRV_Simulable
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/backend/mod_3_NRV_Results.rst b/docs/nrv/backend/mod_3_NRV_Results.rst
deleted file mode 100644
index 3264b334..00000000
--- a/docs/nrv/backend/mod_3_NRV_Results.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.backend.NRV\_Results module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.backend.NRV_Results
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/backend/mod_4_NRV_Singleton.rst b/docs/nrv/backend/mod_4_NRV_Singleton.rst
deleted file mode 100644
index 0b404435..00000000
--- a/docs/nrv/backend/mod_4_NRV_Singleton.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.backend.NRV\_Singleton module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.backend.NRV_Singleton
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/backend/mod_5_parameters.rst b/docs/nrv/backend/mod_5_parameters.rst
deleted file mode 100644
index e97388af..00000000
--- a/docs/nrv/backend/mod_5_parameters.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.backend.parameters module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.backend.parameters
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/backend/mod_6_log_interface.rst b/docs/nrv/backend/mod_6_log_interface.rst
deleted file mode 100644
index b286d661..00000000
--- a/docs/nrv/backend/mod_6_log_interface.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.backend.log\_interface module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.backend.log_interface
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/backend/mod_7_MCore.rst b/docs/nrv/backend/mod_7_MCore.rst
deleted file mode 100644
index 6fa7f241..00000000
--- a/docs/nrv/backend/mod_7_MCore.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.backend.MCore module
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.backend.MCore
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/backend/mod_8_file_handler.rst b/docs/nrv/backend/mod_8_file_handler.rst
deleted file mode 100644
index 6378053a..00000000
--- a/docs/nrv/backend/mod_8_file_handler.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.backend.file\_handler module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.backend.file_handler
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/backend/mod_9_inouts.rst b/docs/nrv/backend/mod_9_inouts.rst
deleted file mode 100644
index 7a34384a..00000000
--- a/docs/nrv/backend/mod_9_inouts.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.backend.inouts module
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.backend.inouts
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/backend/nrv.backend.rst b/docs/nrv/backend/nrv.backend.rst
deleted file mode 100644
index ad5bc7eb..00000000
--- a/docs/nrv/backend/nrv.backend.rst
+++ /dev/null
@@ -1,19 +0,0 @@
-nrv.backend package
-===================
-
-Module contents
----------------
-
-.. automodule:: nrv.backend
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-Submodules
-----------
-
-.. toctree::
-   :glob:
-   :maxdepth: 1
-
-   mod_*
diff --git a/docs/nrv/fmod/FEM/fenics_utils/mod_1_FEMParameters.rst b/docs/nrv/fmod/FEM/fenics_utils/mod_1_FEMParameters.rst
deleted file mode 100644
index 4085e1a4..00000000
--- a/docs/nrv/fmod/FEM/fenics_utils/mod_1_FEMParameters.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.fmod.FEM.fenics\_utils.FEMParameters module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.fmod.FEM.fenics_utils.FEMParameters
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/fmod/FEM/fenics_utils/mod_2_FEMSimulation.rst b/docs/nrv/fmod/FEM/fenics_utils/mod_2_FEMSimulation.rst
deleted file mode 100644
index 040f5d26..00000000
--- a/docs/nrv/fmod/FEM/fenics_utils/mod_2_FEMSimulation.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.fmod.FEM.fenics\_utils.FEMSimulation module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.fmod.FEM.fenics_utils.FEMSimulation
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/fmod/FEM/fenics_utils/mod_3_FEMResults.rst b/docs/nrv/fmod/FEM/fenics_utils/mod_3_FEMResults.rst
deleted file mode 100644
index 5a9c7a39..00000000
--- a/docs/nrv/fmod/FEM/fenics_utils/mod_3_FEMResults.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.fmod.FEM.fenics\_utils.FEMResults module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.fmod.FEM.fenics_utils.FEMResults
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/fmod/FEM/fenics_utils/mod_4_f_materials.rst b/docs/nrv/fmod/FEM/fenics_utils/mod_4_f_materials.rst
deleted file mode 100644
index 9b468f16..00000000
--- a/docs/nrv/fmod/FEM/fenics_utils/mod_4_f_materials.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.fmod.FEM.fenics\_utils.f\_materials module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.fmod.FEM.fenics_utils.f_materials
-   :members:
-   :undoc-members:
-   :show-inheritance:
diff --git a/docs/nrv/fmod/FEM/fenics_utils/mod_5_fenics_materials.rst b/docs/nrv/fmod/FEM/fenics_utils/mod_5_fenics_materials.rst
deleted file mode 100644
index 01e0e8e0..00000000
--- a/docs/nrv/fmod/FEM/fenics_utils/mod_5_fenics_materials.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.fmod.FEM.fenics\_utils.fenics\_materials module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.fmod.FEM.fenics_utils.fenics_materials
-   :members:
-   :undoc-members:
-   :show-inheritance:
diff --git a/docs/nrv/fmod/FEM/fenics_utils/mod_6_layered_materials.rst b/docs/nrv/fmod/FEM/fenics_utils/mod_6_layered_materials.rst
deleted file mode 100644
index 0191f196..00000000
--- a/docs/nrv/fmod/FEM/fenics_utils/mod_6_layered_materials.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.fmod.FEM.fenics\_utils.layered\_materials module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.fmod.FEM.fenics_utils.layered_materials
-   :members:
-   :undoc-members:
-   :show-inheritance:
diff --git a/docs/nrv/fmod/FEM/fenics_utils/nrv.fmod.FEM.fenics_utils.rst b/docs/nrv/fmod/FEM/fenics_utils/nrv.fmod.FEM.fenics_utils.rst
deleted file mode 100644
index 8c34f0b6..00000000
--- a/docs/nrv/fmod/FEM/fenics_utils/nrv.fmod.FEM.fenics_utils.rst
+++ /dev/null
@@ -1,20 +0,0 @@
-nrv.fmod.FEM.fenics\_utils package
-==================================
-
-Module contents
----------------
-
-.. automodule:: nrv.fmod.FEM.fenics_utils
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-Submodules
-----------
-
-.. toctree::
-   :glob:
-   :maxdepth: 1
-
-   mod_*
-
diff --git a/docs/nrv/fmod/FEM/mesh_creator/mod_1_MshCreator.rst b/docs/nrv/fmod/FEM/mesh_creator/mod_1_MshCreator.rst
deleted file mode 100644
index c2c4f516..00000000
--- a/docs/nrv/fmod/FEM/mesh_creator/mod_1_MshCreator.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.fmod.FEM.mesh\_creator.MshCreator module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.fmod.FEM.mesh_creator.MshCreator
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/fmod/FEM/mesh_creator/mod_2_NerveMshCreator.rst b/docs/nrv/fmod/FEM/mesh_creator/mod_2_NerveMshCreator.rst
deleted file mode 100644
index ec61be20..00000000
--- a/docs/nrv/fmod/FEM/mesh_creator/mod_2_NerveMshCreator.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.fmod.FEM.mesh\_creator.NRV\_Msh module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.fmod.FEM.mesh_creator.NRV_Msh
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/fmod/FEM/mesh_creator/mod_3_NRV_Msh.rst b/docs/nrv/fmod/FEM/mesh_creator/mod_3_NRV_Msh.rst
deleted file mode 100644
index ee2f182e..00000000
--- a/docs/nrv/fmod/FEM/mesh_creator/mod_3_NRV_Msh.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.fmod.FEM.mesh\_creator.NerveMshCreator module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.fmod.FEM.mesh_creator.NerveMshCreator
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/fmod/FEM/mesh_creator/nrv.fmod.FEM.mesh_creator.rst b/docs/nrv/fmod/FEM/mesh_creator/nrv.fmod.FEM.mesh_creator.rst
deleted file mode 100644
index 0b55c8d7..00000000
--- a/docs/nrv/fmod/FEM/mesh_creator/nrv.fmod.FEM.mesh_creator.rst
+++ /dev/null
@@ -1,24 +0,0 @@
-nrv.fmod.FEM.mesh\_creator package
-==================================
-
-Module contents
----------------
-
-.. automodule:: nrv.fmod.FEM.mesh_creator
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-Submodules
-----------
-
-.. toctree::
-   :glob:
-   :maxdepth: 1
-
-   mod_*
-
-
-
-
-
diff --git a/docs/nrv/fmod/FEM/mod_1_FEM.rst b/docs/nrv/fmod/FEM/mod_1_FEM.rst
deleted file mode 100644
index f59eeb89..00000000
--- a/docs/nrv/fmod/FEM/mod_1_FEM.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.fmod.FEM.FEM module
-~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.fmod.FEM.FEM
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/fmod/FEM/mod_2_COMSOL_model.rst b/docs/nrv/fmod/FEM/mod_2_COMSOL_model.rst
deleted file mode 100644
index e18f9ae0..00000000
--- a/docs/nrv/fmod/FEM/mod_2_COMSOL_model.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.fmod.FEM.COMSOL\_model module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.fmod.FEM.COMSOL_model
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/fmod/FEM/mod_3_FENICS_model.rst b/docs/nrv/fmod/FEM/mod_3_FENICS_model.rst
deleted file mode 100644
index 1f17a26a..00000000
--- a/docs/nrv/fmod/FEM/mod_3_FENICS_model.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.fmod.FEM.FENICS\_model module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.fmod.FEM.FENICS_model
-   :members:
-   :undoc-members:
-   :show-inheritance:
diff --git a/docs/nrv/fmod/FEM/nrv.fmod.FEM.rst b/docs/nrv/fmod/FEM/nrv.fmod.FEM.rst
deleted file mode 100644
index 4df142a8..00000000
--- a/docs/nrv/fmod/FEM/nrv.fmod.FEM.rst
+++ /dev/null
@@ -1,28 +0,0 @@
-nrv.fmod.FEM package
-====================
-
-Module contents
----------------
-
-.. automodule:: nrv.fmod.FEM
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-Submodules
-----------
-
-.. toctree::
-   :glob:
-   :maxdepth: 1
-
-   mod_*
-
-Subpackages
------------
-
-.. toctree::
-   :glob:
-   :maxdepth: 3
-
-   */nrv.*
\ No newline at end of file
diff --git a/docs/nrv/fmod/mod_1_materials.rst b/docs/nrv/fmod/mod_1_materials.rst
deleted file mode 100644
index e2208e8e..00000000
--- a/docs/nrv/fmod/mod_1_materials.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.fmod.materials module
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.fmod.materials
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/fmod/mod_2_extracellular.rst b/docs/nrv/fmod/mod_2_extracellular.rst
deleted file mode 100644
index ff4d8025..00000000
--- a/docs/nrv/fmod/mod_2_extracellular.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.fmod.extracellular module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.fmod.extracellular
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/fmod/mod_3_electrodes.rst b/docs/nrv/fmod/mod_3_electrodes.rst
deleted file mode 100644
index db558955..00000000
--- a/docs/nrv/fmod/mod_3_electrodes.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.fmod.electrodes module
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.fmod.electrodes
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/fmod/mod_4_stimulus.rst b/docs/nrv/fmod/mod_4_stimulus.rst
deleted file mode 100644
index 26c78901..00000000
--- a/docs/nrv/fmod/mod_4_stimulus.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.fmod.stimulus module
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.fmod.stimulus
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/fmod/mod_5_recording.rst b/docs/nrv/fmod/mod_5_recording.rst
deleted file mode 100644
index 5eb33860..00000000
--- a/docs/nrv/fmod/mod_5_recording.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.fmod.recording module
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.fmod.recording
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/fmod/nrv.fmod.rst b/docs/nrv/fmod/nrv.fmod.rst
deleted file mode 100644
index 241fab63..00000000
--- a/docs/nrv/fmod/nrv.fmod.rst
+++ /dev/null
@@ -1,29 +0,0 @@
-nrv.fmod package
-================
-
-Module contents
----------------
-
-.. automodule:: nrv.fmod
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-Submodules
-----------
-
-.. toctree::
-   :glob:
-   :maxdepth: 1
-
-   mod_*
-
-Subpackages
------------
-
-.. toctree::
-   :glob:
-   :maxdepth: 3
-
-   */nrv.*
-
diff --git a/docs/nrv/nmod/mod_1_axons.rst b/docs/nrv/nmod/mod_1_axons.rst
deleted file mode 100644
index 85d6a665..00000000
--- a/docs/nrv/nmod/mod_1_axons.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-nrv.nmod.axons module
-~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.nmod.axons
-   :members:
-   :undoc-members:
-   :show-inheritance:
-   :exclude-members:
\ No newline at end of file
diff --git a/docs/nrv/nmod/mod_2_axon_pop_generator.rst b/docs/nrv/nmod/mod_2_axon_pop_generator.rst
deleted file mode 100644
index 6d2d4b29..00000000
--- a/docs/nrv/nmod/mod_2_axon_pop_generator.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.nmod.axon_pop_generator module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.nmod.axon_pop_generator
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/nmod/mod_3_unmyelinated.rst b/docs/nrv/nmod/mod_3_unmyelinated.rst
deleted file mode 100644
index b22df598..00000000
--- a/docs/nrv/nmod/mod_3_unmyelinated.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.nmod.unmyelinated module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.nmod.unmyelinated
-   :members:
-   :undoc-members:
-   :show-inheritance:
diff --git a/docs/nrv/nmod/mod_4_myelinated.rst b/docs/nrv/nmod/mod_4_myelinated.rst
deleted file mode 100644
index 590a25a5..00000000
--- a/docs/nrv/nmod/mod_4_myelinated.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.nmod.myelinated module
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.nmod.myelinated
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/nmod/mod_5_fascicles.rst b/docs/nrv/nmod/mod_5_fascicles.rst
deleted file mode 100644
index 3ae5fa33..00000000
--- a/docs/nrv/nmod/mod_5_fascicles.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.nmod.fascicles module
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.nmod.fascicles
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/nmod/mod_6_nerve.rst b/docs/nrv/nmod/mod_6_nerve.rst
deleted file mode 100644
index fe30896d..00000000
--- a/docs/nrv/nmod/mod_6_nerve.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.nmod.nerve module
-~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.nmod.nerve
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/nmod/nrv.nmod.rst b/docs/nrv/nmod/nrv.nmod.rst
deleted file mode 100644
index 74c86bff..00000000
--- a/docs/nrv/nmod/nrv.nmod.rst
+++ /dev/null
@@ -1,37 +0,0 @@
-nrv.nmod package
-================
-
-Module contents
----------------
-
-.. automodule:: nrv.nmod
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-
-Submodules
-----------
-
-.. toctree::
-   :glob:
-   :maxdepth: 1
-
-   mod_*
-
-Subpackages
------------
-
-.. toctree::
-   :glob:
-   :maxdepth: 3
-
-   */nrv.*
-
-
-
-
-
-
-
-
diff --git a/docs/nrv/nmod/results/mod_1_axons_results.rst b/docs/nrv/nmod/results/mod_1_axons_results.rst
deleted file mode 100644
index 9d187f41..00000000
--- a/docs/nrv/nmod/results/mod_1_axons_results.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.nmod.results.axons\_results module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.nmod.results.axons_results
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/nmod/results/mod_2_unmyelinated_results.rst b/docs/nrv/nmod/results/mod_2_unmyelinated_results.rst
deleted file mode 100644
index 4dd49d32..00000000
--- a/docs/nrv/nmod/results/mod_2_unmyelinated_results.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.nmod.results.unmyelinated\_results module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.nmod.results.unmyelinated_results
-   :members:
-   :undoc-members:
-   :show-inheritance:
diff --git a/docs/nrv/nmod/results/mod_3_myelinated_results.rst b/docs/nrv/nmod/results/mod_3_myelinated_results.rst
deleted file mode 100644
index 4f43a36d..00000000
--- a/docs/nrv/nmod/results/mod_3_myelinated_results.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.nmod.results.myelinated\_results module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.nmod.results.myelinated_results
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/nmod/results/mod_4_fascicles_results.rst b/docs/nrv/nmod/results/mod_4_fascicles_results.rst
deleted file mode 100644
index 20981f42..00000000
--- a/docs/nrv/nmod/results/mod_4_fascicles_results.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.nmod.results.fascicles\_results module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.nmod.results.fascicles_results
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/nmod/results/mod_5_nerve_results.rst b/docs/nrv/nmod/results/mod_5_nerve_results.rst
deleted file mode 100644
index 3af04dc8..00000000
--- a/docs/nrv/nmod/results/mod_5_nerve_results.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.nmod.results.nerve\_results module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.nmod.results.nerve_results
-   :members:
-   :undoc-members:
-   :show-inheritance:
diff --git a/docs/nrv/nmod/results/nrv.nmod.restults.rst b/docs/nrv/nmod/results/nrv.nmod.restults.rst
deleted file mode 100644
index 8d0549dd..00000000
--- a/docs/nrv/nmod/results/nrv.nmod.restults.rst
+++ /dev/null
@@ -1,20 +0,0 @@
-nrv.nmod.results package
-========================
-
-Module contents
----------------
-
-.. automodule:: nrv.nmod.results
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-Submodules
-----------
-
-.. toctree::
-   :glob:
-   :maxdepth: 1
-
-   mod_*
-
diff --git a/docs/nrv/nrv.rst b/docs/nrv/nrv.rst
deleted file mode 100644
index afde67dc..00000000
--- a/docs/nrv/nrv.rst
+++ /dev/null
@@ -1,20 +0,0 @@
-nrv Framework
-=============
-
-Module contents
----------------
-
-.. automodule:: nrv
-   :members:
-   :undoc-members:
-   :show-inheritance:
-   :exclude-members: DummyClass
-
-Subpackages
------------
-
-.. toctree::
-   :glob:
-   :maxdepth: 3
-
-   */nrv.*
diff --git a/docs/nrv/optim/mod_1_Problems.rst b/docs/nrv/optim/mod_1_Problems.rst
deleted file mode 100644
index 904fa518..00000000
--- a/docs/nrv/optim/mod_1_Problems.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.optim.Problems module
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.optim.Problems
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/optim/mod_2_CostFunctions.rst b/docs/nrv/optim/mod_2_CostFunctions.rst
deleted file mode 100644
index 81d879eb..00000000
--- a/docs/nrv/optim/mod_2_CostFunctions.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.optim.CostFunctions module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.optim.CostFunctions
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/optim/mod_3_Optimizers.rst b/docs/nrv/optim/mod_3_Optimizers.rst
deleted file mode 100644
index 9cdc796c..00000000
--- a/docs/nrv/optim/mod_3_Optimizers.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.optim.Optimizers module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.optim.Optimizers
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/optim/nrv.optim.rst b/docs/nrv/optim/nrv.optim.rst
deleted file mode 100644
index 98fbdf07..00000000
--- a/docs/nrv/optim/nrv.optim.rst
+++ /dev/null
@@ -1,28 +0,0 @@
-nrv.optim package
-=================
-
-Module contents
----------------
-
-.. automodule:: nrv.optim
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-Submodules
-----------
-
-.. toctree::
-   :glob:
-   :maxdepth: 1
-
-   mod_*
-
-Subpackages
------------
-
-.. toctree::
-   :glob:
-   :maxdepth: 3
-
-   */nrv.*
\ No newline at end of file
diff --git a/docs/nrv/optim/optim_utils/mod_1_ContextModifiers.rst b/docs/nrv/optim/optim_utils/mod_1_ContextModifiers.rst
deleted file mode 100644
index a471b85f..00000000
--- a/docs/nrv/optim/optim_utils/mod_1_ContextModifiers.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.optim.optim_utils.ContextModifiers module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.optim.optim_utils.ContextModifiers
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/optim/optim_utils/mod_2_CostEvaluation.rst b/docs/nrv/optim/optim_utils/mod_2_CostEvaluation.rst
deleted file mode 100644
index e7729106..00000000
--- a/docs/nrv/optim/optim_utils/mod_2_CostEvaluation.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.optim.optim_utils.CostEvaluation module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.optim.optim_utils.CostEvaluation
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/optim/optim_utils/mod_3_optim_results copy.rst b/docs/nrv/optim/optim_utils/mod_3_optim_results copy.rst
deleted file mode 100644
index fadce5d9..00000000
--- a/docs/nrv/optim/optim_utils/mod_3_optim_results copy.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.optim.optim_utils.optim_results module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.optim.optim_utils.optim_results
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/optim/optim_utils/mod_4_OptimFunctions.rst b/docs/nrv/optim/optim_utils/mod_4_OptimFunctions.rst
deleted file mode 100644
index 4f806bbb..00000000
--- a/docs/nrv/optim/optim_utils/mod_4_OptimFunctions.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.optim.optim_utils.OptimFunctions module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.optim.optim_utils.OptimFunctions
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/optim/optim_utils/nrv.optim.optim_utils.rst b/docs/nrv/optim/optim_utils/nrv.optim.optim_utils.rst
deleted file mode 100644
index fb6f8439..00000000
--- a/docs/nrv/optim/optim_utils/nrv.optim.optim_utils.rst
+++ /dev/null
@@ -1,24 +0,0 @@
-nrv.optim.optim_utils package
-=============================
-
-Module contents
----------------
-
-.. automodule:: nrv.optim.optim_utils
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-
-Submodules
-----------
-
-.. toctree::
-   :glob:
-   :maxdepth: 1
-
-   mod_*
-
-
-
-
diff --git a/docs/nrv/utils/cell/mod_1_CL_postprocessing.rst b/docs/nrv/utils/cell/mod_1_CL_postprocessing.rst
deleted file mode 100644
index f94a7dd1..00000000
--- a/docs/nrv/utils/cell/mod_1_CL_postprocessing.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.utils.cell.CL_postprocessing module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.utils.cell.CL_postprocessing
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/utils/cell/mod_2_CL_simulations.rst b/docs/nrv/utils/cell/mod_2_CL_simulations.rst
deleted file mode 100644
index cb16dda7..00000000
--- a/docs/nrv/utils/cell/mod_2_CL_simulations.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.utils.cell.CL_simulations module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.utils.cell.CL_simulations
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/utils/cell/nrv.utils.cell.rst b/docs/nrv/utils/cell/nrv.utils.cell.rst
deleted file mode 100644
index 77016120..00000000
--- a/docs/nrv/utils/cell/nrv.utils.cell.rst
+++ /dev/null
@@ -1,19 +0,0 @@
-nrv.utils.cell package
-======================
-
-Module contents
----------------
-
-.. automodule:: nrv.utils.cell
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-Submodules
-----------
-
-.. toctree::
-   :glob:
-   :maxdepth: 1
-
-   mod_*
diff --git a/docs/nrv/utils/mod_1_units.rst b/docs/nrv/utils/mod_1_units.rst
deleted file mode 100644
index 34f081ad..00000000
--- a/docs/nrv/utils/mod_1_units.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.utils.units module
-~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.utils.units
-   :members:
-   :undoc-members:
-   :show-inheritance:
diff --git a/docs/nrv/utils/mod_2_misc.rst b/docs/nrv/utils/mod_2_misc.rst
deleted file mode 100644
index b16b3bdc..00000000
--- a/docs/nrv/utils/mod_2_misc.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.utils.misc module
-~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.utils.misc
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/utils/mod_3_nrv_function.rst b/docs/nrv/utils/mod_3_nrv_function.rst
deleted file mode 100644
index 6d7cc410..00000000
--- a/docs/nrv/utils/mod_3_nrv_function.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.utils.nrv\_function module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.utils.nrv_function
-   :members:
-   :undoc-members:
-   :show-inheritance:
diff --git a/docs/nrv/utils/mod_4_saving_handler.rst b/docs/nrv/utils/mod_4_saving_handler.rst
deleted file mode 100644
index 2606090a..00000000
--- a/docs/nrv/utils/mod_4_saving_handler.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-nrv.utils.saving\_handler module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. automodule:: nrv.utils.saving_handler
-   :members:
-   :undoc-members:
-   :show-inheritance:
\ No newline at end of file
diff --git a/docs/nrv/utils/nrv.utils.rst b/docs/nrv/utils/nrv.utils.rst
deleted file mode 100644
index b4837153..00000000
--- a/docs/nrv/utils/nrv.utils.rst
+++ /dev/null
@@ -1,29 +0,0 @@
-nrv.utils package
-=================
-
-Module contents
----------------
-
-.. automodule:: nrv.utils
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-
-Submodules
-----------
-
-.. toctree::
-   :glob:
-   :maxdepth: 1
-
-   mod_*
-
-Subpackages
------------
-
-.. toctree::
-   :glob:
-   :maxdepth: 3
-
-   */nrv.*
diff --git a/environment.yml b/environment.yml
new file mode 100644
index 00000000..a54cc8c8
--- /dev/null
+++ b/environment.yml
@@ -0,0 +1,10 @@
+name: nrv-env
+channels:
+  - conda-forge
+dependencies:
+  - python==3.12
+  - pip
+  - fenics-dolfinx==0.8.0 
+  - mpich
+  - pip:
+    - nrv-py
\ No newline at end of file
diff --git a/nrv/__init__ copy.py b/nrv/__init__ copy.py
new file mode 100644
index 00000000..64792baa
--- /dev/null
+++ b/nrv/__init__ copy.py
@@ -0,0 +1,143 @@
+# pylint: skip-file
+""" NRV: NeuRon Virtualizer, modeling of the Nervous System,
+
+NRV is a pythonic framework for simulating bio-electronic phenomena and
+interface-systems, taking into account both neural dynamics and extracellular
+fields. NRV is designed to be accessible to end-user with a basic knowledge of
+python and object-oriented programming, and focuses on providing tools to
+describe a electrophysiological setup (axons, fascicles, nerves...) and
+electrical interfaces (electrodes for stimulation, recording and even
+electrical impedance measurements). Simulations can be performed automatically,
+and optimization algorithms can be interfaced to a simulation to improve
+possibilities of designer novel biomedical approaches.
+
+NRV is open source (under CeCILL license), and developpers pay attention to
+limit the dependencies to open source ressources as well. For scientific
+comparison with existing solutions, NRV has been designed to interface COMSOL,
+however associated code in only maintained and not further developped now. NRV
+relies on NEURON for simulation of neural cell properties, and FenicsX for
+Finite Element computations.
+
+NRV has been developped by contributors from the CELL reserach group at the
+Laboratory ETIS (UMR CNRS 8051), ENSEA - CY Cergy Paris University (France)
+until june 2023, and is now primarily developed and maintained by the
+Bioelectronics group of laboratory IMS (UMR CNRS 5218), INP Bordeaux,
+U. of Bordeaux.
+
+to cite NRV:
+Couppey T., Regnacq L., Giraud R., Romain O., Bornat Y., and Kolbl F. (2024)
+NRV: An opem framework for in silico evaluation of peripheral nerve electrical
+stimulation strategies. PLOS Computational Biology 20(7): e1011826.
+https://doi.org/10.1371/journal.pcbi.1011826
+
+For further detail, help and contact, please visit our website:
+http://nrv-framework.org
+
+We ask developpers and users to respect our code of conduct, accessible
+from the following address:
+https://nrv-framework.org/?page_id=96
+
+"""
+
+__copyright__ = "2023, nrv-framework.org"
+__license__ = "CeCILL"
+__version__ = "1.1.1"
+__title__ = "NeuRon Virtualizer"
+__authors__ = "Florian Kolbl, Roland Giraud, Louis Regnacq, Thomas Couppey"
+__contributors__ = __authors__
+__project__ = "NeuRon Virtualizer (NRV)"
+
+#####################################
+#  check environnement variables    #
+#  check correct NRV configuration  #
+#####################################
+import os
+import inspect
+import platform
+
+
+# GMSH must be imported before neuron to prevent installation issues
+import gmsh
+import neuron
+# create a dummy object to locate frameworks path
+class DummyClass:
+    """Dummy class"""
+
+    pass
+
+nrv_path = os.path.dirname(os.path.abspath(inspect.getsourcefile(DummyClass)))
+root_path = nrv_path.replace("/nrv/", "")
+
+######################
+#  Public interface  #
+######################
+
+# automated compilation of .mod files if not already done
+from .backend import _compileMods
+# direct access to backend (remote unnecessary stuff here)
+from .backend._NRV_Class import load_any
+from .backend._parameters import *
+from .backend._wrappers import *
+
+# direct access to fmod
+from .fmod._materials import *
+from .fmod._electrodes import *
+from .fmod._extracellular import *
+from .fmod._recording import *
+from .fmod.FEM._FEM import *
+from .fmod.FEM._COMSOL_model import *
+from .fmod.FEM._FENICS_model import *
+
+# direct acces to nmod
+from .nmod._axons import *
+from .nmod._unmyelinated import *
+from .nmod._myelinated import *
+from .nmod._fascicles import *
+from .nmod._axon_pop_generator import *
+from .nmod._nerve import *
+
+# direct access to optim
+from .optim._CostFunctions import *
+from .optim._Optimizers import *
+from .optim._Problems import *
+from .optim.optim_utils._ContextModifiers import *
+from .optim.optim_utils._CostEvaluation import *
+from .optim.optim_utils._OptimFunctions import *
+
+# direct access to simple of objects utils
+from .utils._stimulus import *
+from .utils._saving_handler import *
+from .utils._nrv_function import *
+
+# direct access to user interface
+from .ui._NRV_Msh import *
+from .ui._axon_postprocessing import *
+from .ui._axon_simulations import *
+from .ui._fascicle_postprocessing import *
+
+# direct acces to results
+from .nmod.results._axons_results import *
+from .nmod.results._unmyelinated_results import *
+from .nmod.results._myelinated_results import *
+from .nmod.results._fascicles_results import *
+from .nmod.results._nerve_results import *
+
+
+######### May not be requiered at the end ###############
+from .fmod.FEM.mesh_creator._MshCreator import *
+from .fmod.FEM.mesh_creator._NerveMshCreator import *
+from .fmod.FEM.fenics_utils._FEMSimulation import *
+from .fmod.FEM.fenics_utils._FEMParameters import *
+from .fmod.FEM.fenics_utils._FEMResults import *
+from .fmod.FEM.fenics_utils._fenics_materials import *
+from .fmod.FEM.fenics_utils._f_materials import *
+from .fmod.FEM.fenics_utils._layered_materials import *
+########################################################
+
+
+
+
+
+
+
+from .eit._protocol import pyeit_protocol
\ No newline at end of file
diff --git a/nrv/__init__.py b/nrv/__init__.py
index 190e4c8d..bbb7c65f 100644
--- a/nrv/__init__.py
+++ b/nrv/__init__.py
@@ -1,7 +1,51 @@
 # pylint: skip-file
-""" NeuRon Virtualizer, large scale modeling of Peripheral Nervous System with random stimulation waveforms"""
+""" NRV: NeuRon Virtualizer, modeling of the Nervous System,
 
-__copyright__ = "2023, Florian Kolbl"
+NRV is a pythonic framework for simulating bio-electronic phenomena and
+interface-systems, taking into account both neural dynamics and extracellular
+fields. NRV is designed to be accessible to end-user with a basic knowledge of
+python and object-oriented programming, and focuses on providing tools to
+describe a electrophysiological setup (axons, fascicles, nerves...) and
+electrical interfaces (electrodes for stimulation, recording and even
+electrical impedance measurements). Simulations can be performed automatically,
+and optimization algorithms can be interfaced to a simulation to improve
+possibilities of designer novel biomedical approaches.
+
+NRV is open source (under CeCILL license), and developpers pay attention to
+limit the dependencies to open source ressources as well. For scientific
+comparison with existing solutions, NRV has been designed to interface COMSOL,
+however associated code in only maintained and not further developped now. NRV
+relies on NEURON for simulation of neural cell properties, and FenicsX for
+Finite Element computations.
+
+NRV has been developped by contributors from the CELL reserach group at the
+Laboratory ETIS (UMR CNRS 8051), ENSEA - CY Cergy Paris University (France)
+until june 2023, and is now primarily developed and maintained by the
+Bioelectronics group of laboratory IMS (UMR CNRS 5218), INP Bordeaux,
+U. of Bordeaux.
+
+
+.. note::
+  to cite NRV:
+  Couppey T., Regnacq L., Giraud R., Romain O., Bornat Y., and Kolbl F. (2024)
+  NRV: An opem framework for in silico evaluation of peripheral nerve electrical
+  stimulation strategies. PLOS Computational Biology 20(7): e1011826.
+  https://doi.org/10.1371/journal.pcbi.1011826
+
+
+.. SeeAlso::
+   - **General information**: `nrv-framework.org <https://nrv-framework.org>`_
+   - **Discussions and queries**: `Forum NRV <https://nrv-framework.org/forum>`_
+   - **Full code**: `Github repository <https://github.com/nrv-framework/NRV>`_
+
+
+.. note::
+  We kindly ask developpers and users to respect our code of conduct, accessible
+  from the following page: `Code of conduct <https://nrv-framework.org/?page_id=96>`_
+
+"""
+
+__copyright__ = "2023, nrv-framework.org"
 __license__ = "CeCILL"
 __version__ = "1.1.1"
 __title__ = "NeuRon Virtualizer"
@@ -10,91 +54,75 @@
 __project__ = "NeuRon Virtualizer (NRV)"
 
 #####################################
-#  check environnement variables    #
 #  check correct NRV configuration  #
 #####################################
-import os
-import inspect
-import platform
-
 
 # GMSH must be imported before neuron to prevent installation issues
 import gmsh
-# create a dummy object to locate frameworks path
-class DummyClass:
-    """Dummy class"""
-
-    pass
-
-nrv_path = os.path.dirname(os.path.abspath(inspect.getsourcefile(DummyClass)))
-root_path = nrv_path.replace("/nrv/", "")
-# create the environnement variable NRVPATH if it does not exist
-if "NRVPATH" not in os.environ:
-    os.environ["NRVPATH"] = nrv_path
-
-# change the permissions on nrv2calm --> shouldn't be needed anymore
-'''
-if not os.access(nrv_path + "/nrv2calm", os.X_OK):
-    mode = os.stat(nrv_path + "/nrv2calm").st_mode
-    mode |= (mode & 0o444) >> 2  # copy R bits to X
-    os.chmod(nrv_path + "/nrv2calm", mode)
-'''
+import neuron
+from .backend._parameters import parameters
+
+# load configuration module
+from .backend._config import nrv_config
+
+# instanciate configuration
+CONFIG = nrv_config()
+
 ######################
 #  Public interface  #
 ######################
-from .backend import compileMods
-from .backend.parameters import *
-from .backend.NRV_Class import load_any
-from .backend.wrappers import *
-
-from .fmod.materials import *
-from .fmod.electrodes import *
-from .fmod.stimulus import *
-from .fmod.extracellular import *
-from .fmod.recording import *
-from .fmod.FEM.FEM import *
-from .fmod.FEM.COMSOL_model import *
-from .fmod.FEM.FENICS_model import *
+from .backend import _compileMods
+from .backend._NRV_Class import load_any
+from .backend._wrappers import *
+
+from .fmod._materials import *
+from .fmod._electrodes import *
+from .utils._stimulus import *
+from .fmod._extracellular import *
+from .fmod._recording import *
+from .fmod.FEM._FEM import *
+from .fmod.FEM._COMSOL_model import *
+from .fmod.FEM._FENICS_model import *
 
 ######### May not be requiered at the end ###############
-from .fmod.FEM.mesh_creator.MshCreator import *
-from .fmod.FEM.mesh_creator.NerveMshCreator import *
-from .fmod.FEM.mesh_creator.NRV_Msh import *
-from .fmod.FEM.fenics_utils.FEMSimulation import *
-from .fmod.FEM.fenics_utils.FEMParameters import *
-from .fmod.FEM.fenics_utils.FEMResults import *
-from .fmod.FEM.fenics_utils.fenics_materials import *
-from .fmod.FEM.fenics_utils.f_materials import *
-from .fmod.FEM.fenics_utils.layered_materials import *
+from .fmod.FEM.mesh_creator._MshCreator import *
+from .fmod.FEM.mesh_creator._NerveMshCreator import *
+from .ui._NRV_Msh import *
+from .fmod.FEM.fenics_utils._FEMSimulation import *
+from .fmod.FEM.fenics_utils._FEMParameters import *
+from .fmod.FEM.fenics_utils._FEMResults import *
+from .fmod.FEM.fenics_utils._fenics_materials import *
+from .fmod.FEM.fenics_utils._f_materials import *
+from .fmod.FEM.fenics_utils._layered_materials import *
 
 ########################################################
 
-from .nmod.axons import *
-from .nmod.unmyelinated import *
-from .nmod.myelinated import *
-from .nmod.fascicles import *
-from .nmod.axon_pop_generator import *
-from .nmod.nerve import *
+from .nmod._axons import *
+from .nmod._unmyelinated import *
+from .nmod._myelinated import *
+from .nmod._fascicles import *
+from .nmod._axon_pop_generator import *
+from .nmod._nerve import *
 
-from .nmod.results.axons_results import *
-from .nmod.results.unmyelinated_results import *
-from .nmod.results.myelinated_results import *
-from .nmod.results.fascicles_results import *
-from .nmod.results.nerve_results import *
+from .nmod.results._axons_results import *
+from .nmod.results._unmyelinated_results import *
+from .nmod.results._myelinated_results import *
+from .nmod.results._fascicles_results import *
+from .nmod.results._nerve_results import *
 
 
-from .utils.saving_handler import *
-from .utils.nrv_function import *
-from .utils.cell.CL_postprocessing import *
-from .utils.cell.CL_simulations import *
-from .utils.fascicle.FL_postprocessing import *
+from .utils._saving_handler import *
+from .utils._nrv_function import *
+from .ui._axon_postprocessing import *
+from .ui._axon_simulations import *
+from .ui._fascicle_postprocessing import *
 
-from .optim.CostFunctions import *
-from .optim.Optimizers import *
-from .optim.Problems import *
-from .optim.optim_utils.ContextModifiers import *
-from .optim.optim_utils.CostEvaluation import *
-from .optim.optim_utils.OptimFunctions import *
+from .optim._CostFunctions import *
+from .optim._Optimizers import *
+from .optim._Problems import *
+from .optim.optim_utils._ContextModifiers import *
+from .optim.optim_utils._CostEvaluation import *
+from .optim.optim_utils._OptimFunctions import *
 
 
-from .eit.Protocol import pyeit_protocol
\ No newline at end of file
+from .eit._protocol import pyeit_protocol
diff --git a/nrv/_misc/NRV.ini b/nrv/_misc/NRV.ini
index 33e8a031..bb83ea0f 100644
--- a/nrv/_misc/NRV.ini
+++ b/nrv/_misc/NRV.ini
@@ -1,5 +1,6 @@
 [NRV]
 FASCICLE_CPU = 3
+LOAD_FMOD = True
 
 [COMSOL]
 COMSOL_STATUS = True
diff --git a/nrv/_misc/log/NRV.log b/nrv/_misc/log/NRV.log
index e69de29b..43210241 100644
--- a/nrv/_misc/log/NRV.log
+++ b/nrv/_misc/log/NRV.log
@@ -0,0 +1,5 @@
+2024-08-19 12:45:57,152 - Matplotlib is building the font cache; this may take a moment.
+2024-08-19 12:46:08,161 - Failed to extract font properties from /System/Library/Fonts/Apple Color Emoji.ttc: In FT2Font: Could not set the fontsize (invalid pixel size; error code 0x17)
+2024-08-19 12:46:08,307 - Failed to extract font properties from /System/Library/Fonts/Supplemental/NISC18030.ttf: In FT2Font: Could not set the fontsize (invalid pixel size; error code 0x17)
+2024-08-19 12:46:08,548 - Failed to extract font properties from /System/Library/Fonts/LastResort.otf: tuple indices must be integers or slices, not str
+2024-08-19 12:46:08,653 - generated new fontManager
diff --git a/nrv/backend/_GPU.py b/nrv/backend/_GPU.py
new file mode 100644
index 00000000..4ad9bd71
--- /dev/null
+++ b/nrv/backend/_GPU.py
@@ -0,0 +1,134 @@
+from subprocess import Popen, PIPE
+from distutils import spawn
+import os
+import platform
+
+## Class and  FUNCTIONS taken from https://github.com/anderskm/gputil/
+
+
+class GPU:
+    def __init__(
+        self,
+        ID,
+        uuid,
+        load,
+        memoryTotal,
+        memoryUsed,
+        memoryFree,
+        driver,
+        gpu_name,
+        serial,
+        display_mode,
+        display_active,
+        temp_gpu,
+    ):
+        self.id = ID
+        self.uuid = uuid
+        self.load = load
+        self.memoryUtil = float(memoryUsed) / float(memoryTotal)
+        self.memoryTotal = memoryTotal
+        self.memoryUsed = memoryUsed
+        self.memoryFree = memoryFree
+        self.driver = driver
+        self.name = gpu_name
+        self.serial = serial
+        self.display_mode = display_mode
+        self.display_active = display_active
+        self.temperature = temp_gpu
+
+
+def safeFloatCast(strNumber):
+    try:
+        number = float(strNumber)
+    except ValueError:
+        number = float("nan")
+    return number
+
+
+def getGPUs():
+    if platform.system() == "Windows":
+        # If the platform is Windows and nvidia-smi
+        # could not be found from the environment path,
+        # try to find it from system drive with default installation path
+        nvidia_smi = spawn.find_executable("nvidia-smi")
+        if nvidia_smi is None:
+            nvidia_smi = (
+                "%s\\Program Files\\NVIDIA Corporation\\NVSMI\\nvidia-smi.exe"
+                % os.environ["systemdrive"]
+            )
+    else:
+        nvidia_smi = "nvidia-smi"
+
+    # Get ID, processing and memory utilization for all GPUs
+    try:
+        p = Popen(
+            [
+                nvidia_smi,
+                "--query-gpu=index,uuid,utilization.gpu,memory.total,memory.used,memory.free,driver_version,name,gpu_serial,display_active,display_mode,temperature.gpu",
+                "--format=csv,noheader,nounits",
+            ],
+            stdout=PIPE,
+        )
+        stdout, stderror = p.communicate()
+    except:
+        return []
+    output = stdout.decode("UTF-8")
+    # output = output[2:-1] # Remove b' and ' from string added by python
+    # print(output)
+    ## Parse output
+    # Split on line break
+    lines = output.split(os.linesep)
+    # print(lines)
+    numDevices = len(lines) - 1
+    GPUs = []
+    for g in range(numDevices):
+        line = lines[g]
+        # print(line)
+        vals = line.split(", ")
+        # print(vals)
+        for i in range(12):
+            # print(vals[i])
+            if i == 0:
+                deviceIds = int(vals[i])
+            elif i == 1:
+                uuid = vals[i]
+            elif i == 2:
+                gpuUtil = safeFloatCast(vals[i]) / 100
+            elif i == 3:
+                memTotal = safeFloatCast(vals[i])
+            elif i == 4:
+                memUsed = safeFloatCast(vals[i])
+            elif i == 5:
+                memFree = safeFloatCast(vals[i])
+            elif i == 6:
+                driver = vals[i]
+            elif i == 7:
+                gpu_name = vals[i]
+            elif i == 8:
+                serial = vals[i]
+            elif i == 9:
+                display_active = vals[i]
+            elif i == 10:
+                display_mode = vals[i]
+            elif i == 11:
+                temp_gpu = safeFloatCast(vals[i])
+        GPUs.append(
+            GPU(
+                deviceIds,
+                uuid,
+                gpuUtil,
+                memTotal,
+                memUsed,
+                memFree,
+                driver,
+                gpu_name,
+                serial,
+                display_mode,
+                display_active,
+                temp_gpu,
+            )
+        )
+    return GPUs  # (deviceIds, gpuUtil, memUtil)
+
+
+# end of functions taken from GPutils
diff --git a/nrv/backend/MCore.py b/nrv/backend/_MCore.py
similarity index 99%
rename from nrv/backend/MCore.py
rename to nrv/backend/_MCore.py
index 217035b9..c49167f2 100644
--- a/nrv/backend/MCore.py
+++ b/nrv/backend/_MCore.py
@@ -1,8 +1,9 @@
 """
 NRV-Multi-Core/Parallel computing handling.
 """
+
 import numpy as np
-from .NRV_Singleton import NRV_singleton
+from ._NRV_Singleton import NRV_singleton
 
 try:
     import mpi4py.MPI as mpi
@@ -101,7 +102,7 @@ def split_job_from_arrays(self, len_arrays, stype="default"):
         if self.is_alone():
             mask = np.arange(len_arrays)
         else:
-            if stype=="comb":
+            if stype == "comb":
                 mask = np.arange(len_arrays)
                 mask = np.where(self.rank == mask % self.size)[0]
             else:
diff --git a/nrv/backend/NRV_Class.py b/nrv/backend/_NRV_Class.py
similarity index 97%
rename from nrv/backend/NRV_Class.py
rename to nrv/backend/_NRV_Class.py
index f5ec33d2..b91de9a7 100644
--- a/nrv/backend/NRV_Class.py
+++ b/nrv/backend/_NRV_Class.py
@@ -2,6 +2,7 @@
 Module containing a top class from which all other NRV classes inherit.
 This is mainly used to create generic methods such as save and load.
 """
+
 from abc import ABCMeta, abstractmethod
 from copy import deepcopy
 
@@ -10,8 +11,8 @@
 import numpy as np
 from numpy import iterable
 
-from .file_handler import json_dump, json_load
-from .log_interface import pass_debug_info
+from ._file_handler import json_dump, json_load
+from ._log_interface import pass_debug_info
 
 ########################################
 #           check object               #
@@ -251,7 +252,7 @@ def save(self, save=False, fname="nrv_save.json", blacklist=[], **kwargs) -> dic
                     key_dic[key] = {}
                     for i in self.__dict__[key]:
                         key_dic[key][i] = self.__dict__[key][i].save(**kwargs)
-                
+
                 else:
                     key_dic[key] = deepcopy(self.__dict__[key])
         if save:
@@ -298,18 +299,17 @@ def set_parameters(self, **kawrgs) -> None:
         ----------
         ***kwargs
             Key arguments containing one or multiple parameters to set.
-            
+
         Examples
         --------
         As the :class:`~nrv.nmod.myelinated.myelinated` inherits from NRV_class-class parameters, such as diameter and lenght can be set with `set_parameters`.
 
-        >>> import nrv
         >>> ax = nrv.myelinated()
-        >>> ax.d
-        10
+        >>> print(ax.d, ax.L)
+        10, 10000
         >>> ax.set_parameters(d=6, L=1000)
-        >>> ax.d
-        6
+        >>> print(ax.d, ax.L)
+        6, 1000
         """
         for key in kawrgs:
             if key in self.__dict__:
@@ -345,7 +345,7 @@ def load_any(data, **kwargs):
     -------
     nrv_obj: any (NRV_class)
 
-    
+
     """
     if isinstance(data, str):
         key_dic = json_load(data)
diff --git a/nrv/backend/NRV_Results.py b/nrv/backend/_NRV_Results.py
similarity index 86%
rename from nrv/backend/NRV_Results.py
rename to nrv/backend/_NRV_Results.py
index 4e40f94e..a08f895e 100644
--- a/nrv/backend/NRV_Results.py
+++ b/nrv/backend/_NRV_Results.py
@@ -8,10 +8,10 @@
 from collections.abc import Iterable
 from scipy import signal
 
-from .NRV_Class import NRV_class, load_any, abstractmethod, is_NRV_class
-from .log_interface import rise_warning, pass_info
-from ..fmod.stimulus import stimulus
-from .file_handler import json_load
+from ._NRV_Class import NRV_class, load_any, abstractmethod, is_NRV_class
+from ._log_interface import rise_warning, pass_info
+from ..utils._stimulus import stimulus
+from ._file_handler import json_load
 
 
 def generate_results(obj: any, **kwargs):
@@ -45,16 +45,19 @@ def __init__(self, context=None):
 
         if "nrv_type" in context:
             context["result_type"] = context.pop("nrv_type")
-        
+
         # Discard saving for empty results (mostly fo Mcore)
         self.update(context)
         self.__sync()
 
-
     @property
     def to_save(self):
         return "dummy_res" not in self
 
+    @property
+    def is_dummy(self):
+        return "dummy_res" in self
+
     def save(self, save=False, fname="nrv_save.json", blacklist=[], **kwargs):
         save = save and self.to_save
         self.__update_np_keys()
@@ -90,7 +93,12 @@ def __delitem__(self, key):
                 del self.__dict__[key]
             super().__delitem__(key)
 
-    def remove_key(self, keys_to_remove:str|set[str]=[], keys_to_keep:set[str]|None=None, verbose:bool=False):
+    def remove_key(
+        self,
+        keys_to_remove: str | set[str] = [],
+        keys_to_keep: set[str] | None = None,
+        verbose: bool = False,
+    ):
         """
         Remove a key or a list of keys from the results
 
@@ -109,11 +117,17 @@ def remove_key(self, keys_to_remove:str|set[str]=[], keys_to_keep:set[str]|None=
         else:
             if isinstance(keys_to_remove, str):
                 del self[keys_to_remove]
-                pass_info("removed the following key from results: ", keys_to_remove, verbose=verbose)
+                pass_info(
+                    "removed the following key from results: ",
+                    keys_to_remove,
+                    verbose=verbose,
+                )
             else:
                 for key in keys_to_remove:
                     del self[key]
-                    pass_info("removed the following key from results: ", key, verbose=verbose)
+                    pass_info(
+                        "removed the following key from results: ", key, verbose=verbose
+                    )
 
     def update(self, __m, **kwargs) -> None:
         """
@@ -176,19 +190,23 @@ def filter_freq(self, my_key, freq, Q=10):
             fs = 1 / self["dt"]
             if isinstance(f0, Iterable):
                 new_sig = np.zeros(self[my_key].shape)
-                for k in range(len(self[my_key])):
+                for k in range(len(self[my_key])): 
                     new_sig[k, :] = self[my_key][k]
+                    offset = self[my_key][k][0]
+                    new_sig[k, :] = new_sig[k, :] - offset
                     for f in f0:
                         b_notch, a_notch = signal.iirnotch(f, Q, fs)
                         new_sig[k, :] = signal.lfilter(
                             b_notch, a_notch, new_sig[k, :][k]
                         )
+                    new_sig[k, :] = new_sig[k, :] + offset
             else:
                 ##  NOTCH at the stimulation frequency
                 b_notch, a_notch = signal.iirnotch(f0, Q, fs)
                 new_sig = np.zeros(self[my_key].shape)
                 for k in range(len(self[my_key])):
-                    new_sig[k, :] = signal.lfilter(b_notch, a_notch, self[my_key][k])
+                    offset = self[my_key][k][0]
+                    new_sig[k, :] = signal.lfilter(b_notch, a_notch, self[my_key][k] - offset) + offset
             self[my_key + "_filtered"] = new_sig
 
     def plot_stim(self, IDs=None, t_stop=None, N_pts=1000, ax=None, **fig_kwargs):
diff --git a/nrv/backend/NRV_Simulable.py b/nrv/backend/_NRV_Simulable.py
similarity index 98%
rename from nrv/backend/NRV_Simulable.py
rename to nrv/backend/_NRV_Simulable.py
index 1595ac25..35d5df9f 100644
--- a/nrv/backend/NRV_Simulable.py
+++ b/nrv/backend/_NRV_Simulable.py
@@ -4,9 +4,8 @@
 A generic class for all NRV simulable classes (:class:`~nrv.nmod.nerve`, :class:`~nrv.nmod.fascicle`, :class:`~nrv.nmod.myelinated`)
 """
 
-
-from .NRV_Class import NRV_class
-from .NRV_Results import generate_results, sim_results
+from ._NRV_Class import NRV_class
+from ._NRV_Results import generate_results, sim_results
 
 
 def is_NRV_simulable(x):
@@ -24,6 +23,7 @@ def is_NRV_simulable(x):
     """
     return isinstance(x, NRV_simulable)
 
+
 def simulable(x):
     """
     Check if the object x is a :class:`.NRV_simulable`.
@@ -39,11 +39,12 @@ def simulable(x):
     """
     return isinstance(x, NRV_simulable)
 
+
 class NRV_simulable(NRV_class):
     """
     Generic class for all NRV simulable classes (:class:`~nrv.nmod.nerve`, :class:`~nrv.nmod.fascicle`, :class:`~nrv.nmod.myelinated`).
     This class gather commun features to all the simulable object, in particular the :func:`.NRV_simulable.simulate` method.
-    
+
     Note
     ----
     -   All NRV_simulable instance are callable object. When called, the instance :func:`.NRV_simulable.simulate` method is called.
diff --git a/nrv/backend/NRV_Singleton.py b/nrv/backend/_NRV_Singleton.py
similarity index 100%
rename from nrv/backend/NRV_Singleton.py
rename to nrv/backend/_NRV_Singleton.py
diff --git a/nrv/backend/__init__.py b/nrv/backend/__init__.py
index 9afb0b51..dc0bb9d5 100644
--- a/nrv/backend/__init__.py
+++ b/nrv/backend/__init__.py
@@ -1,1 +1,119 @@
-""" NRV Backend library """
+""" backend: code for IO, machine and classes handling
+
+the backend sub-package is dedicated to handling the magic behind all NRV
+computations. The code developed here is not meant to be used directly by the
+end-user, but internally to develop new functionality or maintain other
+sub-packages.
+
+"""
+
+from ._config import nrv_config
+from ._file_handler import (
+    is_iterable,
+    rmv_ext,
+    generate_new_fname,
+    create_folder,
+    check_json_fname,
+    json_dump,
+    json_load,
+    load_dxf_file,
+    NRV_Encoder,
+)
+from ._inouts import (
+    set_attributes,
+    check_function_kwargs,
+    function_to_str,
+    str_to_function,
+)
+from ._log_interface import (
+    init_reporter,
+    set_log_level,
+    rise_error,
+    rise_warning,
+    pass_info,
+    pass_debug_info,
+    progression_popup,
+    prompt_debug,
+    clear_prompt_line,
+    bcolors,
+    pbar,
+)
+from ._MCore import synchronize_processes, Mcore_handler
+from ._NRV_Class import (
+    is_NRV_class,
+    is_NRV_class_list,
+    is_NRV_class_dict,
+    is_NRV_dict,
+    is_NRV_dict_list,
+    is_NRV_dict_dict,
+    is_NRV_object_dict,
+    is_empty_iterable,
+    load_any,
+    NRV_class,
+)
+from ._NRV_Results import generate_results, NRV_results, sim_results
+from ._NRV_Simulable import is_NRV_simulable, simulable, NRV_simulable
+from ._NRV_Singleton import NRV_singleton
+from ._parameters import nrv_parameters
+from ._wrappers import singlecore
+
+submodules = []
+
+classes = [
+    "nrv_config",
+    "NRV_Encoder",
+    "bcolors",
+    "pbar",
+    "Mcore_handler",
+    "NRV_class",
+    "NRV_results",
+    "sim_results",
+    "NRV_simulable",
+    "NRV_singleton",
+    "nrv_parameters",
+]
+
+functions = [
+    "NeuronCompile",
+    "is_iterable",
+    "rmv_ext",
+    "generate_new_fname",
+    "create_folder",
+    "check_json_fname",
+    "json_dump",
+    "json_load",
+    "load_dxf_file",
+    "set_attributes",
+    "check_function_kwargs",
+    "function_to_str",
+    "str_to_function",
+    "init_reporter",
+    "set_log_level",
+    "rise_error",
+    "rise_warning",
+    "pass_info",
+    "pass_debug_info",
+    "progression_popup",
+    "prompt_debug",
+    "clear_prompt_line",
+    "synchronize_processes",
+    "is_NRV_class",
+    "is_NRV_class_list",
+    "is_NRV_class_dict",
+    "is_NRV_dict",
+    "is_NRV_dict_list",
+    "is_NRV_dict_dict",
+    "is_NRV_object_dict",
+    "is_empty_iterable",
+    "load_any",
+    "generate_results",
+    "is_NRV_simulable",
+    "simulable",
+    "singlecore",
+]
+
+__all__ = []
+
+__all__ += submodules
+__all__ += classes
+__all__ += functions
diff --git a/nrv/backend/compileMods.py b/nrv/backend/_compileMods.py
similarity index 83%
rename from nrv/backend/compileMods.py
rename to nrv/backend/_compileMods.py
index ca89554e..bf1cb86d 100644
--- a/nrv/backend/compileMods.py
+++ b/nrv/backend/_compileMods.py
@@ -5,6 +5,7 @@
 """
 
 import os
+from ._parameters import parameters
 
 # test if neuron correctly installed
 # warning: difficult as neuron can be 'mocked' on github and rtd for delploy and help
@@ -13,7 +14,7 @@
 
     nrn_version = nrn.__version__  # this fails :)
 except AttributeError:
-    from .log_interface import rise_warning
+    from ._log_interface import rise_warning
 
     # no Neuron or fake neuron
     rise_warning(
@@ -21,7 +22,7 @@
     )
 else:
     # if true neuron installation
-    dir_path = os.environ["NRVPATH"] + "/_misc/mods/"
+    dir_path = parameters.nrv_path + "/_misc/mods/"
     ls = os.listdir(dir_path)
     test_mods = False
     i = 0
@@ -32,7 +33,7 @@
     def NeuronCompile():
         # path2compiled_mods =  dir_path + "/mods/x86_64"
         path2_mods = dir_path
-        os.system("chmod +x " + os.environ["NRVPATH"] + "/nrv2calm")
+        os.system("chmod +x " + parameters.nrv_path + "/nrv2calm")
         os.system("cd " + path2_mods + "&& nrnivmodl")
 
     if not test_mods:
diff --git a/nrv/backend/_config.py b/nrv/backend/_config.py
new file mode 100644
index 00000000..82f3c063
--- /dev/null
+++ b/nrv/backend/_config.py
@@ -0,0 +1,20 @@
+"""
+Everything about the configuration, gathers :in a singleton:
+* Macine configuration,
+* NRV parameters,
+* ...
+"""
+from ._NRV_Singleton import NRV_singleton
+from ._machine_config import MachineConfig
+from ._parameters import nrv_parameters
+
+class nrv_config(metaclass=NRV_singleton):
+    """ A unique class to handle all the configuration
+    
+    """
+    def __init__(self):
+        self.machine_config = MachineConfig()
+        self.framework_parameters = nrv_parameters()
+
+    def display_machine_config(self):
+        print(self.machine_config)
\ No newline at end of file
diff --git a/nrv/backend/file_handler.py b/nrv/backend/_file_handler.py
similarity index 98%
rename from nrv/backend/file_handler.py
rename to nrv/backend/_file_handler.py
index 911838fe..afb1a539 100644
--- a/nrv/backend/file_handler.py
+++ b/nrv/backend/_file_handler.py
@@ -1,11 +1,12 @@
 """
 NRV-I/O File Handler.
 """
+
 import json
 import os
 import numpy as np
 
-from .log_interface import rise_error, rise_warning, pass_info
+from ._log_interface import rise_error, rise_warning, pass_info
 
 
 #################
diff --git a/nrv/backend/inouts.py b/nrv/backend/_inouts.py
similarity index 77%
rename from nrv/backend/inouts.py
rename to nrv/backend/_inouts.py
index 51b6b380..ab2feed7 100644
--- a/nrv/backend/inouts.py
+++ b/nrv/backend/_inouts.py
@@ -1,8 +1,7 @@
 from collections.abc import Callable
 import inspect
 
-from .log_interface import rise_warning
-
+from ._log_interface import rise_warning
 
 
 def set_attributes(my_object, attributes_dict):
@@ -19,7 +18,7 @@ def set_attributes(my_object, attributes_dict):
     return 0
 
 
-def check_function_kwargs(func:Callable, kwargs:dict)->dict:
+def check_function_kwargs(func: Callable, kwargs: dict) -> dict:
     """
     check that the keys of a dictionnary are arguments of a function and return an updated dictionnary with only valide keys
 
@@ -35,17 +34,19 @@ def check_function_kwargs(func:Callable, kwargs:dict)->dict:
     dict
         updated kwargs dictionnary
     """
-    func_kwargs_set = set(func.__code__.co_varnames[:func.__code__.co_argcount])
+    func_kwargs_set = set(func.__code__.co_varnames[: func.__code__.co_argcount])
     kwargs_set = set(kwargs.keys())
     not_valid_kwargs_set = kwargs_set - func_kwargs_set
     for k in not_valid_kwargs_set:
         kwargs.pop(k)
     return kwargs
 
-def function_to_str(func:Callable)->str:
+
+def function_to_str(func: Callable) -> str:
     lines = inspect.getsource(func)
     return lines
 
-def str_to_function(lines:str)->Callable:
+
+def str_to_function(lines: str) -> Callable:
     lines
-    return lines
\ No newline at end of file
+    return lines
diff --git a/nrv/backend/log_interface.py b/nrv/backend/_log_interface.py
similarity index 95%
rename from nrv/backend/log_interface.py
rename to nrv/backend/_log_interface.py
index 2d1a5880..1adf6840 100644
--- a/nrv/backend/log_interface.py
+++ b/nrv/backend/_log_interface.py
@@ -3,6 +3,7 @@
 
 For the moment, the log interface is managed using the pyswarms reporter class to avoid interference between loggers.
 """
+
 import logging
 import os
 import sys
@@ -10,8 +11,8 @@
 from icecream import ic
 from time import sleep
 
-from .MCore import MCH
-from .parameters import parameters
+from ._MCore import MCH
+from ._parameters import parameters
 
 from pyswarms.utils import Reporter
 
@@ -29,7 +30,7 @@ class bcolors:
 
 
 def init_reporter():
-    rep_nrv = Reporter(log_path=dir_path + "/log/NRV.log")
+    rep_nrv = Reporter(log_path=parameters.nrv_path + "/_misc/log/NRV.log")
     rep_nrv._default_config["handlers"]["default"]["level"] = "CRITICAL"
     rep_nrv._default_config["formatters"]["standard"][
         "format"
@@ -49,7 +50,6 @@ def set_log_level(level, clear_log_file=False):
     return rep_nrv
 
 
-dir_path = os.environ["NRVPATH"] + "/_misc"
 rep_nrv = init_reporter()
 
 
@@ -249,22 +249,22 @@ def pass_debug_info(*args, **kwargs):
             sys.stdout.flush()
 
 
-
-
 ########
 # pbar #
 ########
-class pbar():
+class pbar:
     """
     Progess bar object compatible with MPI
     """
+
     instanciate = True
+
     def __init__(self, n_tot, label=""):
         if not MCH.is_alone():
             label = f"{MCH.rank}: " + label
         self.__instantiate_delay()
         self._pbar = tqdm.tqdm(total=n_tot, desc=label, position=MCH.rank)
-    
+
     def __del__(self):
         del self._pbar
         if MCH.do_master_only_work():
@@ -273,8 +273,8 @@ def __del__(self):
             sys.stdout.flush()
 
     def __instantiate_delay(self):
-        # Dirty hack to prevent skiping two lines 
-        sleep(0.05*(MCH.rank))
+        # Dirty hack to prevent skiping two lines
+        sleep(0.05 * (MCH.rank))
 
     def set_label(self, label=""):
         if not MCH.is_alone():
@@ -334,7 +334,7 @@ def prompt_debug(*args):
     ic(*args)
 
 
-def clear_prompt_line(n:int=1) -> None:
+def clear_prompt_line(n: int = 1) -> None:
     """
     Clear lines of the prompt, to overwrite stuffs.
 
@@ -343,7 +343,7 @@ def clear_prompt_line(n:int=1) -> None:
     n : int, optional
         Number of line to clear, by default 1
     """
-    LINE_UP = '\033[1A'
-    LINE_CLEAR = '\x1b[2K'
+    LINE_UP = "\033[1A"
+    LINE_CLEAR = "\x1b[2K"
     for i in range(n):
-        print(LINE_UP, end=LINE_CLEAR)
\ No newline at end of file
+        print(LINE_UP, end=LINE_CLEAR)
diff --git a/nrv/backend/_machine_config.py b/nrv/backend/_machine_config.py
new file mode 100644
index 00000000..999787ef
--- /dev/null
+++ b/nrv/backend/_machine_config.py
@@ -0,0 +1,263 @@
+import os
+import sys
+import psutil
+
+from ._GPU import getGPUs
+from ._NRV_Singleton import NRV_singleton
+
+
+# miscalleneous constants
+Mem_KBytes = 1024
+Mem_MBytes = Mem_KBytes**2
+Mem_GBytes = Mem_KBytes**3
+# Constants for sanity check
+suported_platforms = [
+    "linux",
+    "darwin",
+    "win32",
+    "cygwin",
+]
+# python min vesion
+NRV_PYTHON_VERSION = {
+    "major": 3,
+    "minor": 12,
+    "patch": 0,
+}
+
+MIN_REQUIREMENTS = {
+    "CPU_ncores": 1,
+    "Memory_size": 8000
+}
+
+
+class MachineConfig(metaclass=NRV_singleton):
+    """Singleton to get all machine properties related to computational performances.
+
+    Parameters
+    ----------
+    memory_unit: int
+        Dividor to express all memomry sizes in a given unit, 
+        Constant already defined, can be:
+        * Mem_KBytes (= 1024)
+        * Mem_MBytes (= Mem_KBytes**2)
+        * Mem_GBytes (= Mem_KBytes**3
+    """
+    def __init__(self, memory_unit=Mem_MBytes):
+        self._explore_OS()
+        self._explore_Python()
+        self._explore_Float()
+        self._explore_CPU()
+        self._explore_GPU()
+        self._explore_memory(unit=memory_unit)
+
+    def __str__(self):
+        current_str = f"""%%%%%%%%%%%%%%%%%%%%%%%%
+%% INFORMATIONS ON OS %%
+%%%%%%%%%%%%%%%%%%%%%%%%
+OS platform: {self.OS_name}
+OS version: {self.OS_version}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%
+%% INFORMATIONS ON CPU %%
+%%%%%%%%%%%%%%%%%%%%%%%%%
+Number of available Cores: {self.CPU_ncores}
+CPU number of bits: {self.CPU_nbits}
+CPU architecture: {self.CPU_arch}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%
+%% INFORMATIONS ON GPU %%
+%%%%%%%%%%%%%%%%%%%%%%%%%
+Number of available Cores: {self.GPU_ncores}
+GPU total memory: {self.GPU_memory_total}
+GPU used memory: {self.GPU_memory_used}
+GPU free memory: {self.GPU_memory_free}
+GPU memory load: {self.GPU_memory_load}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% INFORMATIONS ON MEMORY %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+MEMORY total size: {self.MEMORY_size} {self.MEMORY_unit}
+MEMORY available: {self.MEMORY_available} {self.MEMORY_unit}
+MEMORY available in percent: {self.MEMORY_percent}
+MEMORY used: {self.MEMORY_used} {self.MEMORY_unit}
+MEMORY free: {self.MEMORY_free} {self.MEMORY_unit}
+MEMORY active: {self.MEMORY_active} {self.MEMORY_unit}
+MEMORY inactive: {self.MEMORY_inactive} {self.MEMORY_unit}
+MEMORY wired: {self.MEMORY_wired} {self.MEMORY_unit}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% INFORMATIONS ON PYTHON %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+Python version: {self.Python_version_major}.{self.Python_version_minor}.{self.Python_version_micro}
+Release level: {self.Python_version_releaselevel}
+serial: {self.Python_version_serial}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% INFORMATION ON FLOAT REPRESENTATION %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+Maximum number of decimal digits that can be faithfully represented in a float: {self.dig}
+Difference between 1 and the next representable float: {self.epsilon}
+Mantissa digits: {self.mant_dig}
+Maximum representable finite floats: {self.max}
+Maximum int e such that 10**e, that radix**(e-1), are representable: {self.max_10_exp}, {self.max_exp}
+Minimum positive normalized float: {self.min}
+Minimum int e such that 10**e, that radix**(e-1), is a normalized float{self.min_10_exp}, {self.min_exp}
+Radix of exponent: {self.radix}
+Rounding mode used for arithmetic operations: {self.rounds}
+Float representation style: {self.float_repr_style}"""
+        return current_str
+
+    def _explore_OS(self):
+        self.OS_name = sys.platform
+        self.OS_version = os.uname().release
+
+    def _explore_Python(self):
+        # Python version
+        self.Python_version_major = sys.version_info.major
+        self.Python_version_minor = sys.version_info.minor
+        self.Python_version_micro = sys.version_info.micro
+        self.Python_version_releaselevel = sys.version_info.releaselevel
+        self.Python_version_serial = sys.version_info.serial
+        # imported modules from sys.modules, may be track versions
+
+    def _explore_Float(self):
+        self.dig = sys.float_info.dig
+        self.epsilon = sys.float_info.epsilon
+        self.mant_dig = sys.float_info.mant_dig
+        self.max = sys.float_info.max
+        self.max_10_exp = sys.float_info.max_10_exp
+        self.max_exp = sys.float_info.max_exp
+        self.min = sys.float_info.min
+        self.min_10_exp = sys.float_info.min_10_exp
+        self.min_exp = sys.float_info.min_exp
+        self.radix = sys.float_info.radix
+        self.rounds = sys.float_info.rounds
+        self.float_repr_style = sys.float_repr_style
+
+    def _explore_CPU(self):
+        # get number of cores
+        self.CPU_ncores = os.cpu_count()
+        # get number of bits
+        if sys.maxsize == 2**63 - 1:
+            self.CPU_nbits = 64
+        elif sys.maxsize == 2**31 - 1:
+            self.CPU_nbits = 32
+        else:
+            print("this is really wierd...")
+            self.CPU_nbits = 0.5
+        self.CPU_arch = os.uname().machine
+
+    def _explore_GPU(self):
+        GPUs = getGPUs()
+        self.GPU_ncores = len(GPUs)
+        self.GPU_total_memory = 0
+        self.GPU_memory_total = 0
+        self.GPU_memory_used = 0
+        self.GPU_memory_free = 0
+        self.GPU_memory_load = 0
+        if len(GPUs) > 0:
+            for g in GPUs:
+                self.GPU_memory_total += g.memoryTotal
+                self.GPU_memory_used += g.memoryUsed
+                self.GPU_memory_free += g.memoryFree
+            self.GPU_memory_load = self.GPU_memory_used / self.GPU_memory_total
+
+    def GPU_update(self):
+        GPUs = getGPUs()
+        self.GPU_memory_used = 0
+        self.GPU_memory_free = 0
+        self.GPU_memory_load = 0
+        if len(GPUs) > 0:
+            for g in GPUs:
+                self.GPU_memory_used += g.memoryUsed
+                self.GPU_memory_free += g.memoryFree
+            self.GPU_memory_load = self.GPU_memory_used / self.GPU_memory_total
+
+    def _explore_memory(self, unit=Mem_MBytes):
+        """
+        Note: everything is in MBytes
+        """
+        self.MEMORY_unit_value = unit
+        if unit == Mem_KBytes:
+            self.MEMORY_unit = "kBytes"
+        elif unit == Mem_MBytes:
+            self.MEMORY_unit = "MBytes"
+        else:
+            self.MEMORY_unit = "GBytes"
+        self.MEMORY_size = psutil.virtual_memory().total / self.MEMORY_unit_value
+        self.MEMORY_available = (
+            psutil.virtual_memory().available / self.MEMORY_unit_value
+        )
+        self.MEMORY_percent = psutil.virtual_memory().percent
+        self.MEMORY_used = psutil.virtual_memory().used / self.MEMORY_unit_value
+        self.MEMORY_free = psutil.virtual_memory().free / self.MEMORY_unit_value
+        self.MEMORY_active = psutil.virtual_memory().active / self.MEMORY_unit_value
+        self.MEMORY_inactive = psutil.virtual_memory().inactive / self.MEMORY_unit_value
+        if "linux" not in self.OS_name:
+            self.MEMORY_wired = psutil.virtual_memory().wired / self.MEMORY_unit_value
+        else:
+            self.MEMORY_wired = None
+
+    def memory_update(self):
+        current_MEMORY_available = (
+            psutil.virtual_memory().available / self.MEMORY_unit_value
+        )
+        current_MEMORY_percent = psutil.virtual_memory().percent
+        current_MEMORY_used = psutil.virtual_memory().used / self.MEMORY_unit_value
+        current_MEMORY_free = psutil.virtual_memory().free / self.MEMORY_unit_value
+        current_MEMORY_active = psutil.virtual_memory().active / self.MEMORY_unit_value
+        current_MEMORY_inactive = (
+            psutil.virtual_memory().inactive / self.MEMORY_unit_value
+        )
+        # compute deltas
+        delta_available = current_MEMORY_available - self.MEMORY_available
+        delta_percent = current_MEMORY_percent - self.MEMORY_percent
+        delta_used = current_MEMORY_used - self.MEMORY_used
+        delta_free = current_MEMORY_free - self.MEMORY_free
+        delta_active = current_MEMORY_active - self.MEMORY_active
+        delta_inactive = current_MEMORY_inactive - self.MEMORY_inactive
+        # store new values
+        self.MEMORY_available = current_MEMORY_available
+        self.MEMORY_percent = current_MEMORY_percent
+        self.MEMORY_used = current_MEMORY_used
+        self.MEMORY_free = current_MEMORY_free
+        self.MEMORY_active = current_MEMORY_active
+        self.MEMORY_inactive = current_MEMORY_inactive
+        return (
+            delta_available,
+            delta_percent,
+            delta_used,
+            delta_free,
+            delta_active,
+            delta_inactive,
+        )
+
+    def update(self):
+        self.memory_update()
+        if self.GPU_ncores > 0:
+            self.GPU_update()
+
+    def get_report(self):
+        print(self)
+
+    ### Sanity checks ###
+    def sanity_check(self):
+        # python checks
+        if self.Python_version_major < NRV_PYTHON_VERSION["major"]:
+            print("Warning: Python 2 not supported")
+        elif self.Python_version_minor < NRV_PYTHON_VERSION["minor"]:
+            display_str = (
+                "Warning: Python version detected: "
+                + str(self.Python_version_major)
+                + "."
+                + str(self.Python_version_minor)
+                + "."
+                + str(self.Python_version_micro)
+                + "\n minimal python version is "
+                + str(NRV_PYTHON_VERSION["major"])
+                + "."
+                + str(NRV_PYTHON_VERSION["minor"])
+                + "."
+                + str(NRV_PYTHON_VERSION["patch"])
+            )
+            print(display_str)
diff --git a/nrv/backend/parameters.py b/nrv/backend/_parameters.py
similarity index 89%
rename from nrv/backend/parameters.py
rename to nrv/backend/_parameters.py
index af2114be..f05ab147 100644
--- a/nrv/backend/parameters.py
+++ b/nrv/backend/_parameters.py
@@ -1,12 +1,14 @@
 """
 Access and modify NRV Parameters.
 """
+
 import configparser
 import os
-from .NRV_Singleton import NRV_singleton
+from ._NRV_Singleton import NRV_singleton
+from pathlib import Path
 
 
-class nrv_parameters(metaclass=NRV_singleton):
+class nrv_parameters():
     """
     A class for NRV parameters used to gather parameters
     """
@@ -15,7 +17,8 @@ def __init__(self):
         """
         Initialize the class for parameters
         """
-        self.dir_path = os.environ["NRVPATH"] + "/_misc"
+        self.nrv_path = str(Path(os.path.dirname(__file__)).parent.absolute()) 
+        self.dir_path = self.nrv_path + "/_misc"
         self.config_fname = self.dir_path + "/NRV.ini"
         self.load()
 
@@ -75,6 +78,7 @@ def set_gmsh_ncore(self, n):
         """
         self.GMSH_Ncores = n
 
+
 ###########################
 #   Parameter singleton   #
 ###########################
diff --git a/nrv/backend/wrappers.py b/nrv/backend/_wrappers.py
similarity index 86%
rename from nrv/backend/wrappers.py
rename to nrv/backend/_wrappers.py
index eb463452..9c50c9ca 100644
--- a/nrv/backend/wrappers.py
+++ b/nrv/backend/_wrappers.py
@@ -1,12 +1,15 @@
 """
 NRV-Wrappers and decorator for code clarity
 """
-from .MCore import MCH
+
+from ._MCore import MCH
+
 
 def singlecore(func):
-    '''
+    """
     Decorator to restrict the processing on a signel core, always core 0 (master)
-    '''
+    """
+
     def wrapper(*args, **kwargs):
         results = None
         if MCH.do_master_only_work():
@@ -15,4 +18,5 @@ def wrapper(*args, **kwargs):
         else:
             # do not block other cores
             return results
-    return wrapper
\ No newline at end of file
+
+    return wrapper
diff --git a/nrv/eit/__init__.py b/nrv/eit/__init__.py
new file mode 100644
index 00000000..a4cf3555
--- /dev/null
+++ b/nrv/eit/__init__.py
@@ -0,0 +1,40 @@
+"""Electrical Impedance Tomography - eit: models for neural impedance imaging
+
+eit provides high level models for imaging techniques based on electrical
+impedance sensing for neural activity reconstruction. Tissue properties are
+computed taking into account the temporal and frequencial evolution of neural
+membranes conductivity. Models are based on both Finite Differences (NEURON)
+computations and FEM models.
+
+
+.. warning::
+  The eit sb-package is currently under construction and scientific validation.
+  The code can change fast, results not guaranteed, and developpers do not
+  ensure backwards compatibility.
+
+"""
+
+from ._eit_forward import eit_forward
+from ._eit_inverse import eit_inverse
+from ._eit_utils import crop_fascicle, crop_nerve
+from ._protocol import protocol, pyeit_protocol
+
+submodules = []
+
+classes = [
+    "eit_forward",
+    "eit_inverse",
+    "protocol",
+    "pyeit_protocol",
+]
+
+functions = [
+    "crop_fascicle",
+    "crop_nerve",
+]
+
+__all__ = []
+
+__all__ += submodules
+__all__ += classes
+__all__ += functions
diff --git a/nrv/eit/eit_forward.py b/nrv/eit/_eit_forward.py
similarity index 88%
rename from nrv/eit/eit_forward.py
rename to nrv/eit/_eit_forward.py
index 9eef8aea..ad8b2e55 100644
--- a/nrv/eit/eit_forward.py
+++ b/nrv/eit/_eit_forward.py
@@ -1,12 +1,12 @@
-from ..backend.NRV_Class import NRV_class
-from ..backend.log_interface import rise_error
-
+from ..backend._NRV_Class import NRV_class
+from ..backend._log_interface import rise_error
 
 
 class eit_forward(NRV_class):
     """
     Class allowing to simulate Electircal Impedance Tomography in a nerve
     """
+
     def __init__(self):
         super().__init__()
         self._nerve = None
@@ -24,7 +24,6 @@ def nerve(self, n):
     def nerve(self, n):
         self._nerve = None
 
-
     @property
     def protocol(self):
         return self._protocol
@@ -39,4 +38,3 @@ def protocol(self, p):
 
     def simulate():
         rise_error(NotImplementedError)
-
diff --git a/nrv/eit/eit_inverse.py b/nrv/eit/_eit_inverse.py
similarity index 72%
rename from nrv/eit/eit_inverse.py
rename to nrv/eit/_eit_inverse.py
index 4cbe16a0..bf3041ef 100644
--- a/nrv/eit/eit_inverse.py
+++ b/nrv/eit/_eit_inverse.py
@@ -1,15 +1,12 @@
-from ..backend.NRV_Class import NRV_class
-from ..backend.log_interface import rise_error
-
+from ..backend._NRV_Class import NRV_class
+from ..backend._log_interface import rise_error
 
 
 class eit_inverse(NRV_class):
     """
     Class allowing image reconstruction from ``eit_forward`` results. Based on the `pyEIT` algorithms.
     """
+
     def __init__():
         _protocol = None
         rise_error(NotImplementedError)
-
-
-
diff --git a/nrv/eit/eit_utils.py b/nrv/eit/_eit_utils.py
similarity index 80%
rename from nrv/eit/eit_utils.py
rename to nrv/eit/_eit_utils.py
index b608012d..4d2b0b39 100644
--- a/nrv/eit/eit_utils.py
+++ b/nrv/eit/_eit_utils.py
@@ -1,9 +1,9 @@
-from ..nmod.nerve import nerve
-from ..nmod.fascicles import fascicle
-from ..nmod.myelinated import get_MRG_parameters
+from ..nmod._nerve import nerve
+from ..nmod._fascicles import fascicle
+from ..nmod._myelinated import get_MRG_parameters
 
 
-def crop_fascicle(fasc:fascicle, x0:float, new_l:float)->fascicle:
+def crop_fascicle(fasc: fascicle, x0: float, new_l: float) -> fascicle:
     """_summary_
 
     Parameters
@@ -30,7 +30,8 @@ def crop_fascicle(fasc:fascicle, x0:float, new_l:float)->fascicle:
                 fasc.NoR_relative_position -= int(fasc.NoR_relative_position)
     return fasc
 
-def crop_nerve(nerv:nerve, x0:float, new_l:float)->nerve:
+
+def crop_nerve(nerv: nerve, x0: float, new_l: float) -> nerve:
     """_summary_
 
     Parameters
@@ -50,4 +51,4 @@ def crop_nerve(nerv:nerve, x0:float, new_l:float)->nerve:
     nerv.define_length(new_l)
     for fasc in nerv.fascicles.values:
         fasc = crop_fascicle(fasc, x0, new_l)
-    return nerv
\ No newline at end of file
+    return nerv
diff --git a/nrv/eit/Protocol.py b/nrv/eit/_protocol.py
similarity index 70%
rename from nrv/eit/Protocol.py
rename to nrv/eit/_protocol.py
index f2cbe719..b6217d62 100644
--- a/nrv/eit/Protocol.py
+++ b/nrv/eit/_protocol.py
@@ -1,13 +1,14 @@
-from ..backend.NRV_Class import NRV_class
+from ..backend._NRV_Class import NRV_class
 from copy import deepcopy
 import numpy as np
 
 
 class protocol(NRV_class):
     """
-    Caution not fully implemented.. 
+    Caution not fully implemented..
     First version of a eit protocol class
     """
+
     def __init__(self, p=None):
         super().__init__()
         self._injection = []
@@ -17,13 +18,12 @@ def __init__(self, p=None):
             self._injection = deepcopy(p._injection)
             self._recording = deepcopy(p._recording)
 
-
     @property
     def rec_mat(self):
         m_mat = [[]]
-        for i in range(len(self)-1):
+        for i in range(len(self) - 1):
             m_mat[-1] += [self._recording[i]]
-            if self._injection[i] != self._injection[i+1]:
+            if self._injection[i] != self._injection[i + 1]:
                 m_mat += [[]]
         m_mat[-1] += [list(self._recording[-1])]
         return np.array(m_mat)
@@ -31,13 +31,12 @@ def rec_mat(self):
     @property
     def inj_mat(self):
         e_mat = [self._injection[0]]
-        for i in range(len(self)-1):
-            if self._injection[i] != self._injection[i+1]:
-                e_mat += [self._injection[i+1]]
+        for i in range(len(self) - 1):
+            if self._injection[i] != self._injection[i + 1]:
+                e_mat += [self._injection[i + 1]]
         return np.array(e_mat)
 
-
-    def change_electrode_id(self, oldid:int, newid:int):
+    def change_electrode_id(self, oldid: int, newid: int):
         for i, e in enumerate(self._injection):
             e1, e2 = e
             if oldid == e[0]:
@@ -53,7 +52,6 @@ def change_electrode_id(self, oldid:int, newid:int):
                 e2 = newid
             self._recording[i] = e1, e2
 
-
     def add_injection(self, inj=None):
         if inj is not None:
             self._injection += [inj]
@@ -66,7 +64,6 @@ def add_recording(self, rec=None):
         else:
             self._recording += [self._recording[-1]]
 
-
     def add_patern(self, inj=None, rec=None):
         if len(self) == 0 and (inj is None or rec is None):
             raise IndexError("empty ") from None
@@ -78,13 +75,12 @@ def clear(self):
         self._injection = []
         self._recording = []
 
-
     def push(self, inj=None, rec=None):
-        self.add_patern(inj=inj, rec=rec) 
+        self.add_patern(inj=inj, rec=rec)
 
     def pop(self):
         try:
-            return self._injection.pop() , self._recording.pop()
+            return self._injection.pop(), self._recording.pop()
         except IndexError:
             raise IndexError("pop from an empty stack") from None
 
@@ -94,59 +90,51 @@ def __getitem__(self, index):
     def __len__(self):
         return len(self._injection)
 
-
-    def add_n(self, n:int):
+    def add_n(self, n: int):
         if n + np.min(self) < 0:
             print("Warning: protocol cannot have negative id of electrode")
             print(f"Warning: protocol cannot have negative id of electrode")
             n = np.min(self)
 
-        self._injection = [(n + i, n + j)  for i, j in self._injection]
-        self._recording = [(n + i, n + j)  for i, j in self._recording]
-
-    def mul_n(self, n:int):
-        self._injection = [(n * i, n * j)  for i, j in self._injection]
-        self._recording = [(n * i, n * j)  for i, j in self._recording]
-
+        self._injection = [(n + i, n + j) for i, j in self._injection]
+        self._recording = [(n + i, n + j) for i, j in self._recording]
 
-    def __sub__(self, n:int):
-        """
+    def mul_n(self, n: int):
+        self._injection = [(n * i, n * j) for i, j in self._injection]
+        self._recording = [(n * i, n * j) for i, j in self._recording]
 
-        """
+    def __sub__(self, n: int):
+        """ """
         p = protocol(self)
         p.add_n(-n)
         return p
 
-    def __rsub__(self, n:int):
+    def __rsub__(self, n: int):
         return self.__add__(-n)
 
-    def __add__(self, n:int):
-        """
-
-        """
+    def __add__(self, n: int):
+        """ """
         p = protocol(self)
         p.add_n(n)
         return p
 
-    def __radd__(self, n:int):
+    def __radd__(self, n: int):
         return self.__add__(n)
 
-    def __mul__(self, n:int):
-        """
-
-        """
+    def __mul__(self, n: int):
+        """ """
         p = protocol(self)
         p.mul_n(n)
         return p
 
-    def __rmul__(self, n:int):
+    def __rmul__(self, n: int):
         return self.__add__(n)
 
 
 class pyeit_protocol(protocol):
     def __init__(self, n_elec=8, inj_offset=1, start_elec=0):
         super().__init__()
-        self.n_elec=n_elec
+        self.n_elec = n_elec
         self.inj_offset = inj_offset
         self.start_elec = start_elec
         self.__generate_protocol()
@@ -154,14 +142,17 @@ def __init__(self, n_elec=8, inj_offset=1, start_elec=0):
     def __generate_protocol(self):
         self.clear()
         for i_inj in range(self.n_elec):
-            inj_pat = ((self.start_elec + i_inj)%self.n_elec, (self.start_elec + i_inj + self.inj_offset)%self.n_elec)
+            inj_pat = (
+                (self.start_elec + i_inj) % self.n_elec,
+                (self.start_elec + i_inj + self.inj_offset) % self.n_elec,
+            )
             inj_pat = inj_pat[0], inj_pat[1]
             for i_rec in range(self.n_elec):
-                e = (self.start_elec + i_rec + 1)%self.n_elec
-                e_ = (self.start_elec + i_rec)%self.n_elec
+                e = (self.start_elec + i_rec + 1) % self.n_elec
+                e_ = (self.start_elec + i_rec) % self.n_elec
                 if not e in inj_pat and not e_ in inj_pat:
                     rec_pat = e, e_
-                    if not(rec_pat[0] in inj_pat or rec_pat[1] in inj_pat):
+                    if not (rec_pat[0] in inj_pat or rec_pat[1] in inj_pat):
                         self.add_patern(inj_pat, rec_pat)
         self = self.add_n(1)
 
@@ -170,4 +161,3 @@ def set_parameters(self, **kwds):
             if key in self.__dict__:
                 self.__dict__[key] = kwds[key]
         self.__generate_protocol()
-
diff --git a/nrv/fmod/FEM/COMSOL_model.py b/nrv/fmod/FEM/_COMSOL_model.py
similarity index 96%
rename from nrv/fmod/FEM/COMSOL_model.py
rename to nrv/fmod/FEM/_COMSOL_model.py
index 2df60d30..4f73e1bd 100644
--- a/nrv/fmod/FEM/COMSOL_model.py
+++ b/nrv/fmod/FEM/_COMSOL_model.py
@@ -9,14 +9,15 @@
 import mph
 import numpy as np
 
-from ...backend.file_handler import rmv_ext
-from ...backend.MCore import MCH
-from ...backend.log_interface import rise_warning
-from ...utils.units import V
-from .FEM import *
+from ...backend._file_handler import rmv_ext
+from ...backend._MCore import MCH
+from ...backend._log_interface import rise_warning
+from ...backend._parameters import parameters
+from ...utils._units import V
+from ._FEM import *
 
 # built in COMSOL models
-dir_path = os.environ["NRVPATH"] + "/_misc"
+dir_path = parameters.nrv_path + "/_misc"
 material_library = os.listdir(dir_path + "/comsol_templates/")
 
 ###############
diff --git a/nrv/fmod/FEM/FEM.py b/nrv/fmod/FEM/_FEM.py
similarity index 95%
rename from nrv/fmod/FEM/FEM.py
rename to nrv/fmod/FEM/_FEM.py
index 0958b5d7..0753968a 100644
--- a/nrv/fmod/FEM/FEM.py
+++ b/nrv/fmod/FEM/_FEM.py
@@ -1,11 +1,12 @@
 """
 NRV-:class:`.FEM_model` handling.
 """
+
 from abc import abstractmethod
 
-from ...backend.MCore import MCH
-from ...backend.log_interface import pass_info, rise_warning
-from ...backend.NRV_Class import NRV_class
+from ...backend._MCore import MCH
+from ...backend._log_interface import pass_info, rise_warning
+from ...backend._NRV_Class import NRV_class
 
 ###############
 ## Constants ##
diff --git a/nrv/fmod/FEM/FENICS_lumped_impedance_model.py b/nrv/fmod/FEM/_FENICS_lumped_impedance_model.py
similarity index 93%
rename from nrv/fmod/FEM/FENICS_lumped_impedance_model.py
rename to nrv/fmod/FEM/_FENICS_lumped_impedance_model.py
index 8c5f1259..a63b59ff 100644
--- a/nrv/fmod/FEM/FENICS_lumped_impedance_model.py
+++ b/nrv/fmod/FEM/_FENICS_lumped_impedance_model.py
@@ -9,18 +9,19 @@
 import numpy as np
 from mpi4py import MPI
 
-from ...backend.file_handler import rmv_ext
-from ...utils.units import V, mm
-from ...utils.misc import get_perineurial_thickness
-from ...backend.MCore import MCH, synchronize_processes
-from .fenics_utils.FEMSimulation import FEMSimulation
+from ...backend._file_handler import rmv_ext
+from ...utils._units import V, mm
+from ...utils._misc import get_perineurial_thickness
+from ...backend._MCore import MCH, synchronize_processes
+from ...backend._parameters import parameters
+from .fenics_utils._FEMSimulation import FEMSimulation
 
-from .FENICS_model import FENICS_model
-from .fenics_utils.FEMResults import save_sim_res_list
-from .mesh_creator.NerveMshCreator import NerveMshCreator, ENT_DOM_offset, pi
+from ._FENICS_model import FENICS_model
+from .fenics_utils._FEMResults import save_sim_res_list
+from .mesh_creator._NerveMshCreator import NerveMshCreator, ENT_DOM_offset, pi
 
 # built in FENICS models
-dir_path = os.environ["NRVPATH"] + "/_misc"
+dir_path = parameters.nrv_path + "/_misc"
 # material_library = os.listdir(dir_path+"/fenics_templates/")
 
 ###############
diff --git a/nrv/fmod/FEM/FENICS_model.py b/nrv/fmod/FEM/_FENICS_model.py
similarity index 95%
rename from nrv/fmod/FEM/FENICS_model.py
rename to nrv/fmod/FEM/_FENICS_model.py
index d9971013..1f894040 100644
--- a/nrv/fmod/FEM/FENICS_model.py
+++ b/nrv/fmod/FEM/_FENICS_model.py
@@ -1,6 +1,7 @@
 """
 NRV-:class:`.FENICS_model` handling.
 """
+
 import configparser
 import os
 import time
@@ -8,19 +9,20 @@
 import numpy as np
 from mpi4py import MPI
 
-from ...backend.file_handler import rmv_ext
-from ...utils.units import V, mm
-from ...utils.misc import get_perineurial_thickness
-from ...backend.MCore import MCH, synchronize_processes
-from ...backend.log_interface import rise_warning
-from .fenics_utils.FEMSimulation import FEMSimulation
+from ...backend._file_handler import rmv_ext
+from ...utils._units import V, mm
+from ...utils._misc import get_perineurial_thickness
+from ...backend._MCore import MCH, synchronize_processes
+from ...backend._log_interface import rise_warning
+from ...backend._parameters import parameters
+from .fenics_utils._FEMSimulation import FEMSimulation
 
-from .FEM import FEM_model
-from .fenics_utils.FEMResults import save_sim_res_list
-from .mesh_creator.NerveMshCreator import NerveMshCreator, ENT_DOM_offset, pi
+from ._FEM import FEM_model
+from .fenics_utils._FEMResults import save_sim_res_list
+from .mesh_creator._NerveMshCreator import NerveMshCreator, ENT_DOM_offset, pi
 
 # built in FENICS models
-dir_path = os.environ["NRVPATH"] + "/_misc"
+dir_path = parameters.nrv_path + "/_misc"
 # material_library = os.listdir(dir_path+"/fenics_templates/")
 
 ###############
@@ -35,7 +37,8 @@
 
 fem_verbose = True
 
-def check_sim_dom(sim:FEMSimulation, mesh:NerveMshCreator):
+
+def check_sim_dom(sim: FEMSimulation, mesh: NerveMshCreator):
     """
     Check if all the physical domains of a mesh are linked to a material property.
     This function can either prevent errors or help to debbug
@@ -112,7 +115,7 @@ def __init__(
         self.Perineurium_mat = "perineurium"
         self.Electrodes_mat = 1  # "platinum"
 
-        self.default_fascicle = {"d": 250, "y_c": 0, "z_c": 0, "res": 250/3}
+        self.default_fascicle = {"d": 250, "y_c": 0, "z_c": 0, "res": 250 / 3}
         self.default_electrode = {
             "elec_type": "LIFE",
             "x_c": self.L / 2,
@@ -368,7 +371,13 @@ def reshape_nerve(self, Nerve_D=None, Length=None, y_c=0, z_c=0, res="default"):
             self.__update_parameters()
 
     def reshape_fascicle(
-        self, Fascicle_D, y_c=0, z_c=0, ID=None, Perineurium_thickness=None, res="default"
+        self,
+        Fascicle_D,
+        y_c=0,
+        z_c=0,
+        ID=None,
+        Perineurium_thickness=None,
+        res="default",
     ):
         """
         Reshape a fascicle of the FEM simulation
@@ -632,9 +641,13 @@ def solve(self, comm=None, rank=None):
                 for i_elec in self.j_electrode:
                     if i_elec == "E" + str(E):
                         e_dom = (
-                            ENT_DOM_offset["Surface"] + ENT_DOM_offset["Electrode"] + (2 * E)
+                            ENT_DOM_offset["Surface"]
+                            + ENT_DOM_offset["Electrode"]
+                            + (2 * E)
+                        )
+                        self.j_electrode[i_elec] = self.i_stim / self.sim.get_surface(
+                            e_dom
                         )
-                        self.j_electrode[i_elec] = self.i_stim/self.sim.get_surface(e_dom)
                     else:
                         self.j_electrode[i_elec] = 0
                 self.sim.setup_sim(**self.j_electrode)
diff --git a/nrv/fmod/FEM/__init__.py b/nrv/fmod/FEM/__init__.py
index 16b83933..5118e839 100644
--- a/nrv/fmod/FEM/__init__.py
+++ b/nrv/fmod/FEM/__init__.py
@@ -1,2 +1,39 @@
 """ NeuRon Virtualizer, large scale modeling of Peripheral Nervous System with random stimulation waveforms"""
 """ FEM-fmod librairy"""
+
+from ._FEM import (
+    FEM_model,
+)
+from ._COMSOL_model import (
+    COMSOL_model,
+)
+from ._FENICS_model import (
+    check_sim_dom,
+    FENICS_model,
+)
+from ._FENICS_lumped_impedance_model import (
+    FENICS_lumped_impedance_model
+)
+
+from . import fenics_utils, mesh_creator
+submodules = [
+    "fenics_utils",
+    "mesh_creator",
+]
+
+classes = [
+    "FEM_model",
+    "COMSOL_model",
+    "FENICS_model",
+    "FENICS_lumped_impedance_model",
+]
+
+functions = [
+    "check_sim_dom",
+]
+
+__all__ = []
+
+__all__ += submodules
+__all__ += classes
+__all__ += functions
\ No newline at end of file
diff --git a/nrv/fmod/FEM/fenics_utils/FEMParameters.py b/nrv/fmod/FEM/fenics_utils/_FEMParameters.py
similarity index 98%
rename from nrv/fmod/FEM/fenics_utils/FEMParameters.py
rename to nrv/fmod/FEM/fenics_utils/_FEMParameters.py
index 1b3403e1..03d7b469 100644
--- a/nrv/fmod/FEM/fenics_utils/FEMParameters.py
+++ b/nrv/fmod/FEM/fenics_utils/_FEMParameters.py
@@ -1,11 +1,12 @@
 """
 NRV-:class:`.FEMParameters` handling.
 """
+
 import numpy as np
 
-from ....backend.file_handler import json_dump, json_load, rmv_ext
-from ....backend.log_interface import rise_error, rise_warning
-from ....backend.NRV_Class import NRV_class, is_empty_iterable
+from ....backend._file_handler import json_dump, json_load, rmv_ext
+from ....backend._log_interface import rise_error, rise_warning
+from ....backend._NRV_Class import NRV_class, is_empty_iterable
 
 
 def is_sim_param(X):
diff --git a/nrv/fmod/FEM/fenics_utils/FEMResults.py b/nrv/fmod/FEM/fenics_utils/_FEMResults.py
similarity index 93%
rename from nrv/fmod/FEM/fenics_utils/FEMResults.py
rename to nrv/fmod/FEM/fenics_utils/_FEMResults.py
index b441c63f..87d1e13a 100644
--- a/nrv/fmod/FEM/fenics_utils/FEMResults.py
+++ b/nrv/fmod/FEM/fenics_utils/_FEMResults.py
@@ -10,29 +10,27 @@
 from dolfinx.io.utils import XDMFFile, VTXWriter, VTKFile
 from dolfinx.cpp.mesh import entities_to_geometry
 from dolfinx.geometry import (
-bb_tree,
-compute_colliding_cells,
-compute_collisions_points,
-compute_closest_entity,
-compute_distance_gjk,
-create_midpoint_tree,
+    bb_tree,
+    compute_colliding_cells,
+    compute_collisions_points,
+    compute_closest_entity,
+    compute_distance_gjk,
+    create_midpoint_tree,
 )
 from mpi4py import MPI
 
 
-from ....backend.file_handler import rmv_ext
-from ....backend.log_interface import rise_error, rise_warning
-from ....backend.parameters import parameters
-from ....backend.MCore import MCH, synchronize_processes
-from ....backend.NRV_Class import NRV_class
-from ..mesh_creator.MshCreator import (
+from ....backend._file_handler import rmv_ext
+from ....backend._log_interface import rise_error, rise_warning
+from ....backend._parameters import parameters
+from ....backend._MCore import MCH, synchronize_processes
+from ....backend._NRV_Class import NRV_class
+from ..mesh_creator._MshCreator import (
     is_MshCreator,
     clear_gmsh,
 )
 
 
-
-
 ###############
 ## Functions ##
 ###############
@@ -53,7 +51,7 @@ def is_sim_res(result):
     return isinstance(result, FEMResults)
 
 
-def save_sim_res_list(sim_res_list, fname, dt=1.):
+def save_sim_res_list(sim_res_list, fname, dt=1.0):
     r"""
     save a list of SimResults in a .bp folder which can be open with PrarView
 
@@ -63,14 +61,14 @@ def save_sim_res_list(sim_res_list, fname, dt=1.):
         list of :class:`.FEMResults` to be saved
     fname : str
         File name and path
-    ftype : str 
+    ftype : str
         - if True .bp folder, else saved in a .xdmf file.
     dt : float
         time step between each results
 
     Warning
     -------
-    For this function to work dolfinx and ParaView must be up to date: 
+    For this function to work dolfinx and ParaView must be up to date:
         -   dolfinx \\(\\geq\\) 0.8.0
         -   ParaView \\(\\geq\\) 5.12.0
     """
@@ -84,7 +82,6 @@ def save_sim_res_list(sim_res_list, fname, dt=1.):
     vtxf.close()
 
 
-
 def read_gmsh(mesh, comm=MPI.COMM_WORLD, rank=0, gdim=3):
     """
     Given a mesh_file or a MeshCreator returns mesh cell_tags and facet_tags
@@ -149,7 +146,7 @@ def V_from_meshfile(mesh_file, elem=("Lagrange", 1)):
 
 
 def closest_point_in_mesh(mesh, point, tree, tdim, midpoint_tree):
-    points = np.reshape(point, (1,3))
+    points = np.reshape(point, (1, 3))
     entity = compute_closest_entity(tree, midpoint_tree, mesh, points)
     mesh_geom = mesh.geometry.x
     geom_dofs = entities_to_geometry(mesh._cpp_object, tdim, entity, False)
@@ -157,6 +154,7 @@ def closest_point_in_mesh(mesh, point, tree, tdim, midpoint_tree):
     displacement = compute_distance_gjk(points, mesh_nodes)
     return entity, points[0] - displacement
 
+
 class FEMResults(NRV_class):
     """
     Result of a FEMSimulation.
@@ -217,7 +215,7 @@ def set_sim_result(
 
     def save(self, file, ftype="vtx", overwrite=True, t=0.0):
         fname = rmv_ext(file)
-        if ftype.lower() == "vtx": #and dfx_utd:
+        if ftype.lower() == "vtx":  # and dfx_utd:
             fname += ".bp"
             with VTXWriter(self.domain.comm, fname, self.vout, "bp4") as f:
                 f.write(t)
@@ -300,8 +298,10 @@ def eval(self, X, is_multi_proc=False):
         cells = []
         points_on_proc = []
         tdim = self.domain.geometry.dim
-        n_entities_local = self.domain.topology.index_map(tdim).size_local\
+        n_entities_local = (
+            self.domain.topology.index_map(tdim).size_local
             + self.domain.topology.index_map(tdim).num_ghosts
+        )
         entities = np.arange(n_entities_local, dtype=np.int32)
         midpoint_tree = create_midpoint_tree(self.domain, tdim, entities)
         tree = bb_tree(self.domain, tdim)
@@ -317,13 +317,15 @@ def eval(self, X, is_multi_proc=False):
                     points_on_proc.append(X[i])
                     cells.append(cells_colliding.links(i)[0])
             else:
-                #point not in the mesh
+                # point not in the mesh
                 if len(cell) == 0:
-                    cell, x_closest = closest_point_in_mesh(self.domain, X[i], tree, tdim, midpoint_tree)
+                    cell, x_closest = closest_point_in_mesh(
+                        self.domain, X[i], tree, tdim, midpoint_tree
+                    )
                     rise_warning(
                         X[i], " not found in mesh, value of ", x_closest, " reused"
                     )
-                    #compute_colliding_cells(self.domain, cells_candidates, X)
+                    # compute_colliding_cells(self.domain, cells_candidates, X)
                     cells += [cell[0]]
                 else:
                     cells += [cell[0]]
diff --git a/nrv/fmod/FEM/fenics_utils/FEMSimulation.py b/nrv/fmod/FEM/fenics_utils/_FEMSimulation.py
similarity index 96%
rename from nrv/fmod/FEM/fenics_utils/FEMSimulation.py
rename to nrv/fmod/FEM/fenics_utils/_FEMSimulation.py
index 32dcd7d2..697b81b1 100644
--- a/nrv/fmod/FEM/fenics_utils/FEMSimulation.py
+++ b/nrv/fmod/FEM/fenics_utils/_FEMSimulation.py
@@ -1,6 +1,7 @@
 """
 NRV-:class:`.FEMSimulation` handling.
 """
+
 import os
 import time
 import numpy as np
@@ -31,12 +32,12 @@
 from basix.ufl import element, mixed_element
 
 
-from ....backend.log_interface import pass_info, rise_error, rise_warning
-from ....backend.file_handler import rmv_ext
-from ....utils.units import S, V, m
-from .fenics_materials import fenics_material
-from .FEMParameters import FEMParameters
-from .FEMResults import read_gmsh, FEMResults
+from ....backend._log_interface import pass_info, rise_error, rise_warning
+from ....backend._file_handler import rmv_ext
+from ....utils._units import S, V, m
+from ._fenics_materials import fenics_material
+from ._FEMParameters import FEMParameters
+from ._FEMResults import read_gmsh, FEMResults
 
 # Lists of available solvers and conditioners
 # go to https://petsc4py.readthedocs.io/en/stable/manual/ksp/ for more info
@@ -339,7 +340,12 @@ def __init_domain(self):
             if self.inbound:
                 self.Nspace = self.Ninboundaries + 1
                 ME = [
-                    element(self.elem[0], self.domain.basix_cell(), self.elem[1], dtype=ScalarType)
+                    element(
+                        self.elem[0],
+                        self.domain.basix_cell(),
+                        self.elem[1],
+                        dtype=ScalarType,
+                    )
                     for _ in range(self.Nspace)
                 ]
                 self.multi_elem = mixed_element(ME)
@@ -529,7 +535,13 @@ def get_solver_opt(self):
         return self.petsc_opt
 
     def set_solver_opt(
-        self, ksp_type=None, pc_type=None, ksp_rtol=None, ksp_atol=None, ksp_max_it=None, **kwargs,
+        self,
+        ksp_type=None,
+        pc_type=None,
+        ksp_rtol=None,
+        ksp_atol=None,
+        ksp_max_it=None,
+        **kwargs,
     ):
         """
         set krylov solver options
@@ -653,22 +665,22 @@ def compute_conductance(self, order=None):
         self.__set_material_map()
         V_sigma = self.V
         od = order or self.elem[1]
-        V_sigma = functionspace(
-            self.domain, ("DG", od)
-        )
+        V_sigma = functionspace(self.domain, ("DG", od))
         sigma_out = []
         for i_space in range(self.Nspace):
             sigma = Function(V_sigma)
             for i_domain in self.domainsID:
                 dom_cells = self.subdomains.find(i_domain)
-                dom_dofs = locate_dofs_topological(V_sigma, self.domain.topology.dim, dom_cells)
+                dom_dofs = locate_dofs_topological(
+                    V_sigma, self.domain.topology.dim-1, dom_cells
+                )
                 i_mat = self.get_mixedspace_domain(i_space=i_space, i_domain=i_domain)
                 mat = self.mat_map[i_mat].mat
                 if mat.is_isotropic():
                     val = np.full_like(dom_dofs, mat.sigma, dtype=default_scalar_type)
                 elif not mat.is_func:
-                    #val = mat.sigma_fen.value
-                    _sig = sum(mat.sigma ** 2) ** 0.5
+                    # val = mat.sigma_fen.value
+                    _sig = sum(mat.sigma**2) ** 0.5
                     val = np.full_like(dom_dofs, _sig, dtype=default_scalar_type)
                 elif mat.is_func:
                     sig_ = Function(V_sigma)
@@ -716,7 +728,7 @@ def get_surface(self, dom_id):
         S = assemble_scalar(form(1 * self.ds(dom_id)))
         if self.comm == MPI.COMM_WORLD:
             S = self.comm.reduce(S, op=MPI.SUM, root=0)
-            S = self.comm.bcast(S, root=0)  
+            S = self.comm.bcast(S, root=0)
         return S
 
     def get_domain_potential(self, dom_id, dim=2, space=0):
diff --git a/nrv/fmod/FEM/fenics_utils/__init__.py b/nrv/fmod/FEM/fenics_utils/__init__.py
index c1f0a300..b3fd7dca 100644
--- a/nrv/fmod/FEM/fenics_utils/__init__.py
+++ b/nrv/fmod/FEM/fenics_utils/__init__.py
@@ -1,2 +1,70 @@
 """ NeuRon Virtualizer, large scale modeling of Peripheral Nervous System with random stimulation waveforms"""
 """ FMOD-FEM-FENICS_UTILS librairy"""
+
+from ._f_materials import (
+    f_material,
+    is_f_mat,
+    mat_from_interp,
+    mat_from_csv,
+    load_f_material,
+)
+
+from ._FEMParameters import (
+    is_sim_param,
+    FEMParameters,
+)
+
+from ._FEMResults import (
+    is_sim_res,
+    save_sim_res_list,
+    read_gmsh,
+    domain_from_meshfile,
+    V_from_meshfile,
+    closest_point_in_mesh,
+    FEMResults,
+)
+
+from ._FEMSimulation import FEMSimulation
+
+from ._fenics_materials import fenics_material
+
+from ._layered_materials import (
+    is_lay_mat,
+    get_sig_ap,
+    layered_material,
+)
+
+submodules = [
+
+]
+
+classes = [
+    "f_material",
+    "FEMParameters",
+    "FEMResults",
+    "FEMSimulation",
+    "fenics_material",
+    "layered_material",
+]
+
+functions = [
+    "is_f_mat",
+    "mat_from_interp",
+    "mat_from_csv",
+    "load_f_material",
+    "is_sim_res",
+    "save_sim_res_list",
+    "read_gmsh",
+    "domain_from_meshfile",
+    "V_from_meshfile",
+    "closest_point_in_mesh",
+    "is_lay_mat",
+    "get_sig_ap",
+]
+
+__all__ = []
+
+__all__ += submodules
+__all__ += classes
+__all__ += functions
+
diff --git a/nrv/fmod/FEM/fenics_utils/f_materials.py b/nrv/fmod/FEM/fenics_utils/_f_materials.py
similarity index 85%
rename from nrv/fmod/FEM/fenics_utils/f_materials.py
rename to nrv/fmod/FEM/fenics_utils/_f_materials.py
index bd1f8b37..d583c5a7 100644
--- a/nrv/fmod/FEM/fenics_utils/f_materials.py
+++ b/nrv/fmod/FEM/fenics_utils/_f_materials.py
@@ -1,15 +1,16 @@
 """
 NRV-fenics_materials class handling.
 """
+
 import faulthandler
 import os
 
 import numpy as np
 
-from ....backend.file_handler import json_dump, rmv_ext
-from ....backend.log_interface import rise_warning
-from ....utils.nrv_function import nrv_interp, nrv_function
-from ...materials import (
+from ....backend._file_handler import json_dump, rmv_ext
+from ....backend._log_interface import rise_warning
+from ....utils._nrv_function import nrv_interp, nrv_function
+from ..._materials import (
     is_mat,
     load_material,
     material,
@@ -63,7 +64,7 @@ def save(self, save=False, fname="Fenics_model.json", blacklist=[], **kwargs):
 
     @property
     def is_func(self):
-        return not self.sigma_func is None
+        return not self._sigma_func is None
 
     @property
     def sigma(self):
@@ -75,11 +76,10 @@ def sigma(self):
     @property
     def sigma_func(self):
         return compute_effective_conductivity(
-            sigma=self._sigma_func,
-            epsilon=self.epsilon,
-            freq=self.freq
+            sigma=self._sigma_func, epsilon=self.epsilon, freq=self.freq
         )
-    def set_conductivity_function(self, sigma_func:nrv_function)->None:
+
+    def set_conductivity_function(self, sigma_func: nrv_function) -> None:
         """
         set the conductivity space function for an anisotropic material
 
@@ -91,7 +91,7 @@ def set_conductivity_function(self, sigma_func:nrv_function)->None:
         self.isotrop_cond = False
         self._sigma_func = sigma_func
 
-    def is_function_defined(self)->bool:
+    def is_function_defined(self) -> bool:
         """
         check that the material conductivity is define as a function
 
@@ -107,7 +107,8 @@ def is_function_defined(self)->bool:
 ## Functions ##
 ###############
 
-def is_f_mat(mat:object)->bool:
+
+def is_f_mat(mat: object) -> bool:
     """
     check if an object is a fenics_material, return True if yes, else False
 
@@ -126,9 +127,9 @@ def is_f_mat(mat:object)->bool:
 
 def mat_from_interp(
     X, Y, kind="linear", dx=0.01, interpolator=None, dxdy=None, scale=None, columns=0
-)->f_material:
+) -> f_material:
     """
-    Return a fenics material with a conductivity space function define as the 
+    Return a fenics material with a conductivity space function define as the
     :class:`~nrv.utils.nrv_function.nrv_interp` of X and Y
 
     Parameters
@@ -161,9 +162,9 @@ def mat_from_interp(
     return mat_obj
 
 
-def mat_from_csv(fname:str, **kwargs)->f_material:
+def mat_from_csv(fname: str, **kwargs) -> f_material:
     """
-    Return a fenics material with a conductivity space function define as the 
+    Return a fenics material with a conductivity space function define as the
     :class:`~nrv.utils.nrv_function.nrv_interp` from the value of a .csv file
 
     Parameters
@@ -185,7 +186,8 @@ def mat_from_csv(fname:str, **kwargs)->f_material:
 
     return mat_from_interp(X, Y, **kwargs)
 
-def load_f_material(X:any=None, **kwargs)->f_material:
+
+def load_f_material(X: any = None, **kwargs) -> f_material:
     """
     Return fenics material from an object X
 
@@ -216,15 +218,17 @@ def load_f_material(X:any=None, **kwargs)->f_material:
         mat.set_isotropic_conductivity(X)
     elif np.iterable(X):
         if len(X) == 2:
-            mat = mat_from_interp(X[0,:], X[1,:], **kwargs)
+            mat = mat_from_interp(X[0, :], X[1, :], **kwargs)
         elif len(X) == 3:
             mat = f_material()
             mat.set_anisotropic_conductivity(X[0], X[1], X[2])
     elif hasattr(X, "mat"):
         mat = load_f_material(X.mat)
     if mat is None:
-        rise_warning(TypeError,
-                     f"{type(X)} not convertible in f_material\n",
-                     "empty material generated")
-        mat=f_material()
-    return mat
\ No newline at end of file
+        rise_warning(
+            TypeError,
+            f"{type(X)} not convertible in f_material\n",
+            "empty material generated",
+        )
+        mat = f_material()
+    return mat
diff --git a/nrv/fmod/FEM/fenics_utils/fenics_materials.py b/nrv/fmod/FEM/fenics_utils/_fenics_materials.py
similarity index 91%
rename from nrv/fmod/FEM/fenics_utils/fenics_materials.py
rename to nrv/fmod/FEM/fenics_utils/_fenics_materials.py
index a9af630f..354602ba 100644
--- a/nrv/fmod/FEM/fenics_utils/fenics_materials.py
+++ b/nrv/fmod/FEM/fenics_utils/_fenics_materials.py
@@ -1,6 +1,7 @@
 """
 NRV-fenics_materials class handling.
 """
+
 import faulthandler
 import os
 
@@ -9,19 +10,19 @@
 from petsc4py.PETSc import ScalarType
 from ufl import as_tensor
 
-from ....backend.file_handler import json_dump, rmv_ext
-from ....backend.log_interface import rise_warning
-from ....backend.NRV_Class import NRV_class
-from ....utils.nrv_function import nrv_interp
-from ...materials import is_mat, load_material
-from .f_materials import load_f_material
+from ....backend._file_handler import json_dump, rmv_ext
+from ....backend._log_interface import rise_warning
+from ....backend._NRV_Class import NRV_class
+from ....backend._parameters import parameters
+from ....utils._nrv_function import nrv_interp
+from ..._materials import is_mat, load_material
+from ._f_materials import load_f_material
 
 # enable faulthandler to ease "segmentation faults" debug
 faulthandler.enable()
 
 # get the built-in material librairy
-dir_path = os.environ["NRVPATH"] + "/_misc"
-
+dir_path = parameters.nrv_path + "/_misc"
 
 
 ####################
@@ -39,7 +40,7 @@ class fenics_material(NRV_class):
         generate the fenics material from mat attribute
     """
 
-    def __init__(self, mat:any=None):
+    def __init__(self, mat: any = None):
         """
         initialisation of the fenics_material
         """
@@ -49,7 +50,6 @@ def __init__(self, mat:any=None):
         self.elem = ("Discontinuous Lagrange", 1)
         self.UN = 1
 
-
     ## Save and Load mehtods
     def save(self, save=False, fname="Fenics_model.json", blacklist=[], **kwargs):
         """
@@ -162,4 +162,4 @@ def update_fenics_sigma(self, domain=None, elem=None, UN=None, id=None):
                     ]
                 )
             else:
-                    self._sigma_fen.interpolate(_sig)
+                self._sigma_fen.interpolate(_sig)
diff --git a/nrv/fmod/FEM/fenics_utils/layered_materials.py b/nrv/fmod/FEM/fenics_utils/_layered_materials.py
similarity index 74%
rename from nrv/fmod/FEM/fenics_utils/layered_materials.py
rename to nrv/fmod/FEM/fenics_utils/_layered_materials.py
index a665b769..7346e603 100644
--- a/nrv/fmod/FEM/fenics_utils/layered_materials.py
+++ b/nrv/fmod/FEM/fenics_utils/_layered_materials.py
@@ -1,21 +1,22 @@
 """
 NRV-fenics_materials class handling.
 """
+
 import faulthandler
 import os
 
 import numpy as np
 
-from ....backend.file_handler import json_dump, rmv_ext
-from ....backend.log_interface import rise_warning
-from ....utils.nrv_function import nrv_interp
-from ...materials import (
+from ....backend._file_handler import json_dump, rmv_ext
+from ....backend._log_interface import rise_warning
+from ....utils._nrv_function import nrv_interp
+from ..._materials import (
     is_mat,
     load_material,
     material,
     compute_effective_conductivity,
 )
-from .f_materials import f_material, load_f_material
+from ._f_materials import f_material, load_f_material
 
 # enable faulthandler to ease "segmentation faults" debug
 faulthandler.enable()
@@ -25,7 +26,7 @@
 ###############
 
 
-def is_lay_mat(mat:object)->bool:
+def is_lay_mat(mat: object) -> bool:
     """
     check if an object is a fenics_material, return True if yes, else False
 
@@ -43,15 +44,14 @@ def is_lay_mat(mat:object)->bool:
 
 
 def get_sig_ap(sig_in, sig_lay, alpha_lay):
-    """
-
-    """
+    """ """
 
-    _alpha_lay = 1/alpha_lay
-    _alpha_in = 1/(1-1/_alpha_lay)
+    _alpha_lay = 1 / alpha_lay
+    _alpha_in = 1 / (1 - 1 / _alpha_lay)
     _sig1 = sig_in * _alpha_in
     _sig2 = sig_lay * _alpha_lay
-    return (_sig1 * _sig2)/(_sig1 + _sig2)
+    return (_sig1 * _sig2) / (_sig1 + _sig2)
+
 
 ####################
 ## material class ##
@@ -69,7 +69,9 @@ class layered_material(f_material):
         generate the fenics material from mat attribute
     """
 
-    def __init__(self, mat_in:any=None, mat_lay:any=None, alpha_lay:float=0.01):
+    def __init__(
+        self, mat_in: any = None, mat_lay: any = None, alpha_lay: float = 0.01
+    ):
         """
         initialisation of the fenics_material
         """
@@ -82,10 +84,10 @@ def __init__(self, mat_in:any=None, mat_lay:any=None, alpha_lay:float=0.01):
     def is_isotropic(self) -> bool:
         return self.mat_in.is_isotropic() and self.mat_lay.is_isotropic()
 
-    def is_function_defined(self)->bool:
+    def is_function_defined(self) -> bool:
         return self.mat_in.is_func or self.mat_lay.is_func
-    
-    def set_frequency(self, freq: float, set_in: bool=False) -> None:
+
+    def set_frequency(self, freq: float, set_in: bool = False) -> None:
         self.mat_lay.set_frequency(freq)
         if set_in:
             self.mat_in.set_frequency(freq)
diff --git a/nrv/fmod/FEM/mesh_creator/MshCreator.py b/nrv/fmod/FEM/mesh_creator/_MshCreator.py
similarity index 98%
rename from nrv/fmod/FEM/mesh_creator/MshCreator.py
rename to nrv/fmod/FEM/mesh_creator/_MshCreator.py
index 6b07ba60..4f30d43b 100644
--- a/nrv/fmod/FEM/mesh_creator/MshCreator.py
+++ b/nrv/fmod/FEM/mesh_creator/_MshCreator.py
@@ -1,18 +1,19 @@
 """
 NRV-:class:`.MshCreator` handling.
 """
+
 import math
 import os
 
 import gmsh
 import numpy as np
 
-from ....backend.file_handler import rmv_ext
-from ....backend.log_interface import pass_info, rise_error, rise_warning
-from ....backend.NRV_Class import NRV_class
-from ....backend.parameters import parameters
+from ....backend._file_handler import rmv_ext
+from ....backend._log_interface import pass_info, rise_error, rise_warning
+from ....backend._NRV_Class import NRV_class
+from ....backend._parameters import parameters
 
-dir_path = os.environ["NRVPATH"] + "/_misc"
+dir_path = parameters.nrv_path + "/_misc"
 
 
 ###############
@@ -417,7 +418,7 @@ def add_cone(self, x=0, y=0, z=0, L=5, R1=1, R2=0):
             id of the added object
         """
         if self.D == 3:
-            parameters = {"x": x, "y": y, "z": z, "L": L, "R1": R1, "R2":R2}
+            parameters = {"x": x, "y": y, "z": z, "L": L, "R1": R1, "R2": R2}
             cone = self.model.occ.addCone(x, y, z, L, 0, 0, R1, R2)
             self.model.occ.synchronize()
             bounds = self.model.getEntities(dim=2)[-3:]
@@ -432,7 +433,6 @@ def add_cone(self, x=0, y=0, z=0, L=5, R1=1, R2=0):
             rise_warning("Not added : add_cylinder requiere 3D mesh")
             return None
 
-
     def rotate(self, volume, angle, x=0, y=0, z=0, ax=0, ay=0, az=0, rad=True):
         """
         rotate volume
@@ -540,17 +540,17 @@ def n_domains(self):
 
     @property
     def domains_1D(self):
-        I = np.where(self.dim_domains==1)
+        I = np.where(self.dim_domains == 1)
         return self.id_domains[I]
 
     @property
     def domains_2D(self):
-        I = np.where(self.dim_domains==2)
+        I = np.where(self.dim_domains == 2)
         return self.id_domains[I]
 
     @property
     def domains_3D(self):
-        I = np.where(self.dim_domains==3)
+        I = np.where(self.dim_domains == 3)
         return self.id_domains[I]
 
     ##############################################################################################
diff --git a/nrv/fmod/FEM/mesh_creator/NerveMshCreator.py b/nrv/fmod/FEM/mesh_creator/_NerveMshCreator.py
similarity index 94%
rename from nrv/fmod/FEM/mesh_creator/NerveMshCreator.py
rename to nrv/fmod/FEM/mesh_creator/_NerveMshCreator.py
index 5738f6b4..80fdc993 100644
--- a/nrv/fmod/FEM/mesh_creator/NerveMshCreator.py
+++ b/nrv/fmod/FEM/mesh_creator/_NerveMshCreator.py
@@ -1,17 +1,19 @@
 """
 NRV-:class:`.NerveMshCreator` handling.
 """
+
 from cmath import phase
 import numpy as np
 from math import log10, floor
 
-from ....backend.NRV_Class import NRV_class, load_any
-from ....backend.log_interface import rise_error, rise_warning
-from ....backend.MCore import MCH
-#from ....nmod.myelinated import myelinated
-from ....utils.units import mm
-from ....backend.file_handler import rmv_ext
-from .MshCreator import MshCreator, pi
+from ....backend._NRV_Class import NRV_class, load_any
+from ....backend._log_interface import rise_error, rise_warning
+from ....backend._MCore import MCH
+
+# from ....nmod.myelinated import myelinated
+from ....utils._units import mm
+from ....backend._file_handler import rmv_ext
+from ._MshCreator import MshCreator, pi
 
 ENT_DOM_offset = {
     "Volume": 0,
@@ -202,7 +204,7 @@ def compute_mesh(self, master_only=True):
         """
         Compute mesh geometry, domains and resolution and then generate the mesh
         """
-        if  MCH.do_master_only_work() or not master_only:
+        if MCH.do_master_only_work() or not master_only:
             self.compute_geo()
             self.compute_domains()
             self.compute_res()
@@ -380,7 +382,17 @@ def remove_fascicles(self, ID=None):
             del self.fascicles[ID]
             self.N_fascicle -= 1
 
-    def reshape_axon(self, d, y=0, z=0, ID=None, myelinated=False, res="default", res_node="default",**kwargs):
+    def reshape_axon(
+        self,
+        d,
+        y=0,
+        z=0,
+        ID=None,
+        myelinated=False,
+        res="default",
+        res_node="default",
+        **kwargs,
+    ):
         """
         Reshape a axon of the FEM simulation
 
@@ -410,16 +422,18 @@ def reshape_axon(self, d, y=0, z=0, ID=None, myelinated=False, res="default", re
             res_node = res / 3
 
         self.axons[ID] = kwargs
-        self.axons[ID].update({
-            "y": y,
-            "z": z,
-            "d": d,
-            "myelinated": myelinated,
-            "res": res,
-            "res_node": res_node,
-            "face": [],
-            "volume": [],
-        })
+        self.axons[ID].update(
+            {
+                "y": y,
+                "z": z,
+                "d": d,
+                "myelinated": myelinated,
+                "res": res,
+                "res_node": res_node,
+                "face": [],
+                "volume": [],
+            }
+        )
 
     def add_electrode(self, elec_type, ID=None, res="default", **kwargs):
         """ """
@@ -543,7 +557,6 @@ def __is_fascicle(self, ID, dx, dy, dz, com, dim_key):
         )
         return status_test and size_test and com_test
 
-
     def __is_axon_node(self, ID, dx, dy, dz, com, dim_key):
         """
         Internal use only: check if volume is axon ID or face is external face of axon ID
@@ -567,20 +580,24 @@ def __is_axon_node(self, ID, dx, dy, dz, com, dim_key):
         # Already computed
         if not axon["myelinated"]:
             return False
-        
+
         # test good diameter
-        size_test = np.allclose([dx, dy, dz], [axon["node_l"], axon["node_d"], axon["node_d"]])
+        size_test = np.allclose(
+            [dx, dy, dz], [axon["node_l"], axon["node_d"], axon["node_d"]]
+        )
 
         # test first and last node
         if "first_node_l" in axon and not size_test:
-            size_test = np.allclose([dx, dy, dz], [axon["first_node_l"], axon["node_d"], axon["node_d"]])
+            size_test = np.allclose(
+                [dx, dy, dz], [axon["first_node_l"], axon["node_d"], axon["node_d"]]
+            )
         if "last_node_l" in axon and not size_test:
-            size_test = np.allclose([dx, dy, dz], [axon["last_node_l"], axon["node_d"], axon["node_d"]])
+            size_test = np.allclose(
+                [dx, dy, dz], [axon["last_node_l"], axon["node_d"], axon["node_d"]]
+            )
 
         # test center of mass in axon
-        com_test = np.allclose(
-            com[1:], (axon["y"], axon["z"])
-        )
+        com_test = np.allclose(com[1:], (axon["y"], axon["z"]))
         return size_test and com_test
 
     def __is_axon(self, ID, dx, dy, dz, com, dim_key):
@@ -604,14 +621,12 @@ def __is_axon(self, ID, dx, dy, dz, com, dim_key):
         """
         axon = self.axons[ID]
         # Already computed
-        status_test = True#axon[dim_key] is None
+        status_test = True  # axon[dim_key] is None
         # test good diameter
         size_test = np.allclose([dy, dz], [axon["d"], axon["d"]])
         size_test &= not np.isclose(dx, 0)
         # test center of mass in axon
-        com_test = np.allclose(
-            com[1:], (axon["y"], axon["z"]), atol=axon["d"] / 2
-        )
+        com_test = np.allclose(com[1:], (axon["y"], axon["z"]), atol=axon["d"] / 2)
         return status_test and size_test and com_test
 
     def __is_CUFF_MP_electrode(self, ID, rc, dx, teta, com, dim_key):
@@ -749,7 +764,7 @@ def __link_entity_domains(self, dim):
             for j in self.axons:
                 if self.__is_axon_node(j, bd_x, bd_y, bd_z, ent_com[i], key):
                     node_id = int(ent_com[i][0] // self.axons[j]["deltax"])
-                    self.axons[j]["nodes_"+key][node_id] = [entities[i][1]]
+                    self.axons[j]["nodes_" + key][node_id] = [entities[i][1]]
                 elif self.__is_axon(j, bd_x, bd_y, bd_z, ent_com[i], key):
                     self.axons[j][key] += [entities[i][1]]
 
@@ -824,13 +839,16 @@ def compute_entity_domain(self):
             if ax["myelinated"]:
                 for i_node in range(len(ax["nodes_volume"])):
                     node_id = 2 * i_node
-                    n = floor(log10(node_id+1)+1)
+                    n = floor(log10(node_id + 1) + 1)
                     ax_id = (ENT_DOM_offset["Axon"] + (2 * j)) * 10**n
                     id_ph = node_id + ax_id
-                    self.add_domains(obj_IDs=ax["nodes_volume"][i_node], phys_ID=id_ph, dim=3)
+                    self.add_domains(
+                        obj_IDs=ax["nodes_volume"][i_node], phys_ID=id_ph, dim=3
+                    )
                     id_ph += ENT_DOM_offset["Surface"]
-                    self.add_domains(obj_IDs=ax["nodes_face"][i_node], phys_ID=id_ph, dim=2)
-
+                    self.add_domains(
+                        obj_IDs=ax["nodes_face"][i_node], phys_ID=id_ph, dim=2
+                    )
 
         for j in self.electrodes:
             id_ph = ENT_DOM_offset["Electrode"] + (2 * j)
@@ -928,9 +946,7 @@ def compute_res(self):
             self.is_refined = True
 
     def __refine_axon(self, axon):
-        """
-        
-        """
+        """ """
         # First set the field for unmyelinated axon or myelin
         fields = [
             self.refine_entities(
@@ -955,7 +971,6 @@ def __refine_axon(self, axon):
                 ]
         return fields
 
-
     def __refine_Outer_box(self, alpha=0.1):
         """ """
         if not self.default_res["Outerbox_tresholded"]:
@@ -993,22 +1008,24 @@ def add_axon(self, ID):
         Note
         ----
          - if the axon is unmyelinated this method add only a cylinder to the mesh
-        
+
         Parameters
         ----------
         """
         axon = self.axons[ID]
         res_min = axon["res_node"]
         if not axon["myelinated"]:
-            self.add_cylinder(0, axon["y"], axon["z"], self.L, axon["d"]/2)
+            self.add_cylinder(0, axon["y"], axon["z"], self.L, axon["d"] / 2)
         else:
-            axon.update({
-                "L": self.L,
-                "rec":"all",
-                "N_seg_per_sec":True,
-                "__NRVObject__":True,
-                "nrv_type":"myelinated",
-            })
+            axon.update(
+                {
+                    "L": self.L,
+                    "rec": "all",
+                    "N_seg_per_sec": True,
+                    "__NRVObject__": True,
+                    "nrv_type": "myelinated",
+                }
+            )
             # Ideally it would be easier to use: ax = myelinated(**axon)
             # But myelinated cannot be imported without causing an import loop
             ax = load_any(data=axon)
@@ -1017,11 +1034,11 @@ def add_axon(self, ID):
             n_nodes = 0
             for sec in ax.axon_path_type[1:-1]:
                 if sec == "node":
-                    r_sec = ax.nodeD/2
+                    r_sec = ax.nodeD / 2
                     l_sec = ax.nodelength
                     n_nodes += 1
                 else:
-                    r_sec = ax.d/2
+                    r_sec = ax.d / 2
                     if sec == "MYSA":
                         l_sec = ax.paralength1
                     elif sec == "FLUT":
@@ -1030,7 +1047,7 @@ def add_axon(self, ID):
                         l_sec = ax.interlength
 
                 # mrege the first (last) section with the next (previous) when it is too small
-                if  abs(x - l_sec) < res_min:
+                if abs(x - l_sec) < res_min:
                     init_l += l_sec
                     ax.axon_path_type.pop(0)
                     x += l_sec
@@ -1041,20 +1058,20 @@ def add_axon(self, ID):
                     x += l_sec
             # adding first section
             if ax.axon_path_type[0] == "node":
-                r_sec = ax.nodeD/2
+                r_sec = ax.nodeD / 2
                 n_nodes += 1
                 self.axons[ID]["first_node_l"] = ax.first_section_size + init_l
             else:
-                r_sec = ax.d/2
+                r_sec = ax.d / 2
             self.add_cylinder(0, ax.y, ax.z, ax.first_section_size + init_l, r_sec)
             # adding first section
             if ax.axon_path_type[-1] == "node":
-                r_sec = ax.nodeD/2
+                r_sec = ax.nodeD / 2
                 n_nodes += 1
-                self.axons[ID]["last_node_l"] = self.L-x
+                self.axons[ID]["last_node_l"] = self.L - x
             else:
-                r_sec = ax.d/2
-            self.add_cylinder(x, ax.y, ax.z, self.L-x, r_sec)
+                r_sec = ax.d / 2
+            self.add_cylinder(x, ax.y, ax.z, self.L - x, r_sec)
 
             self.axons[ID]["node_d"] = ax.nodeD
             self.axons[ID]["node_l"] = ax.nodelength
@@ -1064,7 +1081,6 @@ def add_axon(self, ID):
             self.axons[ID]["nodes_face"] = [None for _ in range(n_nodes)]
             del ax
 
-
     def add_LIFE(
         self, ID=None, x_c=0, y_c=0, z_c=0, length=1000, d=25, is_volume=False
     ):
@@ -1154,8 +1170,13 @@ def add_CUFF(
             self.electrodes[ID]["kwargs"]["insulator_offset"] = insulator_offset
             self.electrodes[ID]["volume"] = []
             self.electrodes[ID]["face"] = []
-            if self.electrodes[ID]["res"] > min(contact_length, insulator_thickness) / 2:
-                self.electrodes[ID]["res"] = min(contact_length, insulator_thickness) / 2
+            if (
+                self.electrodes[ID]["res"]
+                > min(contact_length, insulator_thickness) / 2
+            ):
+                self.electrodes[ID]["res"] = (
+                    min(contact_length, insulator_thickness) / 2
+                )
 
         x_active = x_c - contact_length / 2
         y_active = self.y_c
diff --git a/nrv/fmod/FEM/mesh_creator/__init__.py b/nrv/fmod/FEM/mesh_creator/__init__.py
index 91996db3..b8f26d38 100644
--- a/nrv/fmod/FEM/mesh_creator/__init__.py
+++ b/nrv/fmod/FEM/mesh_creator/__init__.py
@@ -1,2 +1,36 @@
 """ NeuRon Virtualizer, large scale modeling of Peripheral Nervous System with random stimulation waveforms"""
 """ fmod-FEM-mesh_creator librairy"""
+
+
+from ._MshCreator import (
+    is_MshCreator,
+    clear_gmsh,
+    MshCreator,
+)
+from ._NerveMshCreator import (
+    is_NerveMshCreator,
+    NerveMshCreator,
+)
+
+submodules = []
+
+classes = [
+    "MshCreator",
+    "NerveMshCreator",
+]
+
+functions = [
+    "mesh_from_electrode",
+    "mesh_from_extracellular_context",
+    "mesh_from_fascicle",
+    "mesh_from_nerve",
+    "is_MshCreator",
+    "clear_gmsh",
+    "is_NerveMshCreator",
+]
+
+__all__ = []
+
+__all__ += submodules
+__all__ += classes
+__all__ += functions
\ No newline at end of file
diff --git a/nrv/fmod/__init__.py b/nrv/fmod/__init__.py
index 1eb885df..7f131b53 100644
--- a/nrv/fmod/__init__.py
+++ b/nrv/fmod/__init__.py
@@ -1,2 +1,112 @@
-""" NeuRon Virtualizer, large scale modeling of Peripheral Nervous System with random stimulation waveforms"""
-""" Fmod librairy for field models"""
+""" FIELD Models - fmod: handles extracellular field models.
+
+fmod hosts the code to compute extracellular electrical fields and quantities.
+Such quantity can result from both:
+
+
+* electrical stimulation, handled by injecting stimulation current waveforms
+  on electrodes. Associated computations can be performed using analitical 
+  approach (fast but relying on strong hypotheses), or using Finite Element 
+  models,
+* the activity of the cells. In this second case, computations are for the 
+  moment only performed with an analitical approach.
+
+
+Finite Elements solver can be chosen between COMSOL (requieres extra license, 
+this is not the recommended choice and is maintained only for comparison with 
+existing results in the litterature) and FenicsX. This last solution is fully open
+source and should be preferred. In this case, geometries are meshed using GMSH. All FEM
+computations are handled by a subpackage called ``FEM`` (seel below).
+
+.. note::
+  for scientific details of how nmod works and an overview of the general
+  implementation, refer to the 'Scientific foundations' section of the
+  documentation.
+
+"""
+
+
+from ._electrodes import (
+    is_FEM_electrode,
+    is_CUFF_electrode,
+    is_LIFE_electrode,
+    is_analytical_electrode,
+    load_any_electrode,
+    check_electrodes_overlap,
+    electrode,
+    point_source_electrode,
+    FEM_electrode,
+    LIFE_electrode,
+    CUFF_electrode,
+    CUFF_MP_electrode,
+    
+)
+from ._extracellular import (
+    is_extra_stim,
+    is_analytical_extra_stim,
+    is_FEM_extra_stim,
+    load_any_extracel_context,
+    extracellular_context,
+    stimulation,
+    FEM_stimulation,
+)
+from ._materials import (
+    is_mat,
+    get_mat_file_as_dict,
+    load_material,
+    compute_effective_conductivity,
+    material,
+)
+from ._recording import (
+    is_recording_point,
+    is_recorder,
+    NodeD_interpol,
+    recording_point,
+    recorder,
+)
+
+from . import FEM
+submodules = [
+    "FEM",
+]
+
+classes = [
+    "material",
+    "electrode",
+    "point_source_electrode",
+    "FEM_electrode",
+    "LIFE_electrode",
+    "CUFF_electrode",
+    "CUFF_MP_electrode",
+    "extracellular_context",
+    "stimulation",
+    "FEM_stimulation",
+    "recording_point",
+    "recorder",
+]
+
+functions = [
+    "is_FEM_electrode",
+    "is_CUFF_electrode",
+    "is_LIFE_electrode",
+    "is_analytical_electrode",
+    "is_extra_stim",
+    "is_analytical_extra_stim",
+    "is_FEM_extra_stim",
+    "is_mat",
+    "is_recording_point",
+    "is_recorder",
+    "load_any_electrode",
+    "load_any_extracel_context",
+    "load_material",
+    "check_electrodes_overlap",
+    "get_mat_file_as_dict",
+    "compute_effective_conductivity",
+    "NodeD_interpol",
+]
+
+__all__ = []
+
+__all__ += submodules
+__all__ += classes
+__all__ += functions
diff --git a/nrv/fmod/electrodes.py b/nrv/fmod/_electrodes.py
similarity index 94%
rename from nrv/fmod/electrodes.py
rename to nrv/fmod/_electrodes.py
index fe5913dd..6c479708 100644
--- a/nrv/fmod/electrodes.py
+++ b/nrv/fmod/_electrodes.py
@@ -1,14 +1,15 @@
 """
 NRV-:class:`.electrode` handling.
 """
+
 import faulthandler
 
 import numpy as np
 import matplotlib.pyplot as plt
 
-from ..backend.file_handler import json_load
-from ..backend.log_interface import rise_error, rise_warning
-from ..backend.NRV_Class import NRV_class, abstractmethod
+from ..backend._file_handler import json_load
+from ..backend._log_interface import rise_error, rise_warning
+from ..backend._NRV_Class import NRV_class, abstractmethod
 
 # enable faulthandler to ease "segmentation faults" debug
 faulthandler.enable()
@@ -116,6 +117,7 @@ class electrode(NRV_class):
     """
     Objet for generic electrode description. Each electrode has an ID and a position.
     """
+
     @abstractmethod
     def __init__(self, ID=0):
         """
@@ -234,19 +236,16 @@ def translate(self, x=None, y=None, z=None):
         self.clear_footprint()
 
     @abstractmethod
-    def plot(
-        self, axes:plt.axes, color:str="gold",**kwgs
-    )->None:
+    def plot(self, axes: plt.axes, color: str = "gold", **kwgs) -> None:
         pass
 
 
-
-
 class point_source_electrode(electrode):
     """
     Point source electrode. Inherite from electrode. The electrode is punctual and act as a\
     monopole.
     """
+
     def __init__(self, x=0, y=0, z=0, ID=0):
         """
         Instantiation of a Point source electrode
@@ -311,8 +310,8 @@ def compute_footprint(self, x, y, z, mat):
                 )
             )
 
-    def plot(self, axes: plt.axes, color: str="gold", **kwgs) -> None:
-        if ("nerve_d" in kwgs):
+    def plot(self, axes: plt.axes, color: str = "gold", **kwgs) -> None:
+        if "nerve_d" in kwgs:
             del kwgs["nerve_d"]
         axes.plot(self.y, self.z, ".", color=color, **kwgs)
 
@@ -321,6 +320,7 @@ class FEM_electrode(electrode):
     """
     Electrode located in Finite Element Model in Comsol
     """
+
     @abstractmethod
     def __init__(self, label, ID=0):
         """
@@ -344,6 +344,7 @@ def set_footprint(self, V_1mA):
         """
         self.footprint = np.asarray(V_1mA)
 
+
 class LIFE_electrode(FEM_electrode):
     """
     Longitudinal IntraFascicular Electrode for FEM models
@@ -412,13 +413,15 @@ def parameter_model(self, model, res="default"):
                 res=res,
             )
 
-    def plot(self, axes: plt.axes, color: str="gold", **kwgs) -> None:
-        axes.add_patch(plt.Circle(
-            (self.y, self.z),
-            self.D / 2,
-            color=color,
-            fill=True,
-        ))
+    def plot(self, axes: plt.axes, color: str = "gold", **kwgs) -> None:
+        axes.add_patch(
+            plt.Circle(
+                (self.y, self.z),
+                self.D / 2,
+                color=color,
+                fill=True,
+            )
+        )
 
 
 class CUFF_electrode(FEM_electrode):
@@ -530,21 +533,17 @@ def parameter_model(self, model, res="default"):
                 res=res,
             )
 
-    def plot(self, axes: plt.axes, color: str="gold", **kwgs) -> None:
+    def plot(self, axes: plt.axes, color: str = "gold", **kwgs) -> None:
         if "nerve_d" in kwgs:
             rad = kwgs["nerve_d"] / 2
             del kwgs["nerve_d"]
-            axes.add_patch(plt.Circle(
-                (0, 0),
-                rad,
-                color=color,
-                fill=False,
-                linewidth=2,
-                **kwgs
-            ))
+            axes.add_patch(
+                plt.Circle((0, 0), rad, color=color, fill=False, linewidth=2, **kwgs)
+            )
         else:
             rise_warning("Diameter has to be specifie to plot CUFF electrodes")
 
+
 class CUFF_MP_electrode(CUFF_electrode):
     """
     MultiPolar CUFF electrode for FEM models
@@ -641,15 +640,17 @@ def plot(self, axes: plt.axes, color: str = "gold", **kwgs) -> None:
             elec_theta = 0.9 * 2 * np.pi / self.N_contact
             for i in range(self.N_contact):
                 theta_ = 2 * i * np.pi / self.N_contact
-                axes.add_patch(plt.Wedge(
-                    (0, 0),
-                    rad,
-                    theta1 = theta_,
-                    theta2 = theta_ + elec_theta,
-                    color=color,
-                    fill=False,
-                    linewidth=2,
-                    **kwgs
-                ))
+                axes.add_patch(
+                    plt.Wedge(
+                        (0, 0),
+                        rad,
+                        theta1=theta_,
+                        theta2=theta_ + elec_theta,
+                        color=color,
+                        fill=False,
+                        linewidth=2,
+                        **kwgs
+                    )
+                )
         else:
             rise_warning("Diameter has to be specifie to plot CUFF MP electrodes")
diff --git a/nrv/fmod/extracellular.py b/nrv/fmod/_extracellular.py
similarity index 97%
rename from nrv/fmod/extracellular.py
rename to nrv/fmod/_extracellular.py
index de2084da..99f87415 100644
--- a/nrv/fmod/extracellular.py
+++ b/nrv/fmod/_extracellular.py
@@ -1,25 +1,26 @@
 """
 NRV-:class:`.extracellular_context` handling.
 """
+
 import faulthandler
 
 import numpy as np
 import matplotlib.pyplot as plt
 
-from ..backend.file_handler import json_load
-from ..backend.log_interface import rise_error, rise_warning
-from ..backend.MCore import MCH
-from ..backend.NRV_Class import NRV_class, is_empty_iterable
-from ..utils.misc import get_perineurial_thickness
-from .electrodes import (
+from ..backend._file_handler import json_load
+from ..backend._log_interface import rise_error, rise_warning
+from ..backend._MCore import MCH
+from ..backend._NRV_Class import NRV_class, is_empty_iterable
+from ..utils._misc import get_perineurial_thickness
+from ._electrodes import (
     is_analytical_electrode,
     is_FEM_electrode,
     check_electrodes_overlap,
 )
-from .FEM.COMSOL_model import COMSOL_model, COMSOL_Status
-from .FEM.FENICS_model import FENICS_model
-from .materials import load_material, is_mat
-from .stimulus import get_equal_timing_copies
+from .FEM._COMSOL_model import COMSOL_model, COMSOL_Status
+from .FEM._FENICS_model import FENICS_model
+from ._materials import load_material, is_mat
+from ..utils._stimulus import get_equal_timing_copies
 
 # enable faulthandler to ease "segmentation faults" debug
 faulthandler.enable()
@@ -284,8 +285,7 @@ def change_stimulus_from_electrode(self, ID_elec, stimulus):
 
     def plot(self, axes: plt.axes, color: str = "gold", **kwgs) -> None:
         for electrode in self.electrodes:
-            electrode.plot(axes, color , **kwgs)
-
+            electrode.plot(axes, color, **kwgs)
 
 
 class stimulation(extracellular_context):
@@ -359,8 +359,8 @@ class FEM_stimulation(extracellular_context):
     """
     FEM_based_simulation object are designed to connect all other objects required to compute the external potential voltage for axons using FEM :
 
-    - Shape and positon of the nerve 
-    - Shape and position of each fascicle 
+    - Shape and positon of the nerve
+    - Shape and position of each fascicle
     - the materials for the FEM stimulation : endoneurium, perineurium, epineurium and external material
     - a list of electrode(s)
     - a list of corresponding current stimuli
@@ -546,7 +546,13 @@ def reshape_nerve(self, Nerve_D=None, Length=None, y_c=0, z_c=0, res="default"):
                 )
 
     def reshape_fascicle(
-        self, Fascicle_D, y_c=0, z_c=0, ID=None, Perineurium_thickness=None, res="default"
+        self,
+        Fascicle_D,
+        y_c=0,
+        z_c=0,
+        ID=None,
+        Perineurium_thickness=None,
+        res="default",
     ):
         """
         Reshape a fascicle of the FEM simulation
@@ -560,7 +566,7 @@ def reshape_fascicle(
         z_c         : float
             Fascicle center y-coodinate in µm, 0 by default
         Perineurium_thickness   :float
-            Thickness of the Perineurium sheet surounding the fascicles in µm. If None, thickness is determined according to the fascicle diameter 
+            Thickness of the Perineurium sheet surounding the fascicles in µm. If None, thickness is determined according to the fascicle diameter
         ID          : int
             If the simulation contains more than one fascicles, ID number of the fascicle to reshape as in COMSOL
         res         : float or "default"
@@ -583,9 +589,7 @@ def reshape_fascicle(
                     self.model.set_parameter(
                         "Fascicle_" + str(ID) + "_z_c", str(z_c) + "[um]"
                     )
-                self.model.set_parameter(
-                    "Perineurium_thickness", str(p_th) + "[um]"
-                )
+                self.model.set_parameter("Perineurium_thickness", str(p_th) + "[um]")
             else:
                 self.model.reshape_fascicle(
                     Fascicle_D=Fascicle_D,
diff --git a/nrv/fmod/materials.py b/nrv/fmod/_materials.py
similarity index 85%
rename from nrv/fmod/materials.py
rename to nrv/fmod/_materials.py
index c76f39c8..80375747 100644
--- a/nrv/fmod/materials.py
+++ b/nrv/fmod/_materials.py
@@ -1,19 +1,21 @@
 """
 NRV-:class:`.material` handling.
 """
+
 import faulthandler
 import os
 import numpy as np
 from scipy.constants import pi, epsilon_0
 
-from ..backend.log_interface import rise_warning
-from ..backend.NRV_Class import NRV_class
+from ..backend._log_interface import rise_warning
+from ..backend._NRV_Class import NRV_class
+from ..backend._parameters import parameters
 
 # enable faulthandler to ease "segmentation faults" debug
 faulthandler.enable()
 
 # get the built-in material librairy
-dir_path = os.environ["NRVPATH"] + "/_misc"
+dir_path = parameters.nrv_path + "/_misc"
 material_library = os.listdir(dir_path + "/materials/")
 
 ###############
@@ -94,11 +96,11 @@ def load_material(f_material):
     return mat_obj
 
 
-def compute_effective_conductivity(sigma:float, epsilon:float, freq:float)->float:
+def compute_effective_conductivity(sigma: float, epsilon: float, freq: float) -> float:
     r"""
     return the effective conductivity of the material.
     Two cases are psooible:
-    
+
         - purely conductive material (when both `epsilon` or `freq` are set)
 
         .. math:: \sigma_{eff} = \sigma
@@ -112,9 +114,10 @@ def compute_effective_conductivity(sigma:float, epsilon:float, freq:float)->floa
     sigma   : float
         conductivity
     """
-    if epsilon is None or freq is None :
+    if epsilon is None or freq is None:
         return sigma
-    return abs(sigma+2j*pi*freq*epsilon_0*epsilon)
+    return abs(sigma + 2j * pi * freq * epsilon_0 * epsilon)
+
 
 ####################
 ## material class ##
@@ -123,7 +126,7 @@ class material(NRV_class):
     """
     a class for material, where all the physical properties constants are stored.
 
-    by default materials in NRV are considerated as purely conductive. Yet, 
+    by default materials in NRV are considerated as purely conductive. Yet,
     """
 
     def __init__(self):
@@ -146,7 +149,6 @@ def __init__(self):
         self.epsilon = None
         self.freq = None
 
-
     @property
     def sigma(self):
         """
@@ -155,13 +157,11 @@ def sigma(self):
         if not self.is_isotropic():
             return np.array([self.sigma_xx, self.sigma_yy, self.sigma_zz])
         return compute_effective_conductivity(
-            sigma=self._sigma,
-            epsilon=self.epsilon,
-            freq=self.freq
+            sigma=self._sigma, epsilon=self.epsilon, freq=self.freq
         )
 
     @property
-    def sigma_xx(self)->float:
+    def sigma_xx(self) -> float:
         """
         get the conductivity of the material along ox
         """
@@ -169,14 +169,11 @@ def sigma_xx(self)->float:
             rise_warning("Isotropic conductor sigma_xx is sigma")
             return self.sigma
         return compute_effective_conductivity(
-            sigma=self._sigma_xx,
-            epsilon=self.epsilon,
-            freq=self.freq
+            sigma=self._sigma_xx, epsilon=self.epsilon, freq=self.freq
         )
 
-
     @property
-    def sigma_yy(self)->float:
+    def sigma_yy(self) -> float:
         """
         get the conductivity of the material along oy
         """
@@ -184,14 +181,11 @@ def sigma_yy(self)->float:
             rise_warning("Isotropic conductor sigma_yy is sigma")
             return self.sigma
         return compute_effective_conductivity(
-            sigma=self._sigma_yy,
-            epsilon=self.epsilon,
-            freq=self.freq
+            sigma=self._sigma_yy, epsilon=self.epsilon, freq=self.freq
         )
 
-
     @property
-    def sigma_zz(self)->float:
+    def sigma_zz(self) -> float:
         """
         get the conductivity of the material along oz
         """
@@ -199,13 +193,9 @@ def sigma_zz(self)->float:
             rise_warning("Isotropic conductor sigma_zz is sigma")
             return self.sigma
         return compute_effective_conductivity(
-            sigma=self._sigma_zz,
-            epsilon=self.epsilon,
-            freq=self.freq
+            sigma=self._sigma_zz, epsilon=self.epsilon, freq=self.freq
         )
 
-
-
     def save_material(self, save=False, fname="material.json"):
         rise_warning("save_material is a deprecated method use save")
         self.save(save=save, fname=fname)
@@ -214,7 +204,7 @@ def load_material(self, data="material.json"):
         rise_warning("load_material is a deprecated method use load")
         self.load(data=data)
 
-    def set_name(self, name:str)->None:
+    def set_name(self, name: str) -> None:
         """
         set a name to a material
 
@@ -225,7 +215,7 @@ def set_name(self, name:str)->None:
         """
         self.name = name
 
-    def set_source(self, source:str)->None:
+    def set_source(self, source: str) -> None:
         """
         set a source to a material. Note that this source is a string without spaces
 
@@ -236,7 +226,7 @@ def set_source(self, source:str)->None:
         """
         self.source = source
 
-    def set_isotropic_conductivity(self, sigma:float)-> None:
+    def set_isotropic_conductivity(self, sigma: float) -> None:
         """
         set the conductivity for an isotropic material
 
@@ -248,7 +238,9 @@ def set_isotropic_conductivity(self, sigma:float)-> None:
         self.isotrop_cond = True
         self._sigma = float(sigma)
 
-    def set_anisotropic_conductivity(self, sigma_xx:float, sigma_yy:float, sigma_zz:float)->None:
+    def set_anisotropic_conductivity(
+        self, sigma_xx: float, sigma_yy: float, sigma_zz: float
+    ) -> None:
         """
         set the conductivity tensor for an anisotropic material
 
@@ -266,7 +258,7 @@ def set_anisotropic_conductivity(self, sigma_xx:float, sigma_yy:float, sigma_zz:
         self._sigma_yy = float(sigma_yy)
         self._sigma_zz = float(sigma_zz)
 
-    def is_isotropic(self)->bool:
+    def is_isotropic(self) -> bool:
         """
         check that the material is isotropic or not, return true if isotropic, else false
 
@@ -278,7 +270,7 @@ def is_isotropic(self)->bool:
         return self.isotrop_cond
 
     ## Permitivity relatied methods
-    def set_permitivity(self, epsilon:float)->None:
+    def set_permitivity(self, epsilon: float) -> None:
         """
         set the relative permitivity of the material.
 
@@ -294,7 +286,7 @@ def set_permitivity(self, epsilon:float)->None:
         """
         self.epsilon = float(epsilon)
 
-    def set_frequency(self, freq:float)->None:
+    def set_frequency(self, freq: float) -> None:
         """
         set the frequency of the electric field in the material
 
@@ -305,7 +297,7 @@ def set_frequency(self, freq:float)->None:
         """
         self.freq = float(freq)
 
-    def clear_frequency(self)->None:
+    def clear_frequency(self) -> None:
         """
         set the woking frequency to None
 
@@ -321,4 +313,3 @@ def is_permitive(self):
         check if the material permitivity and the electric field frequency are set
         """
         return self.epsilon is not None and self.freq is not None
-
diff --git a/nrv/fmod/recording.py b/nrv/fmod/_recording.py
similarity index 99%
rename from nrv/fmod/recording.py
rename to nrv/fmod/_recording.py
index 46b1af79..8db6f9a4 100644
--- a/nrv/fmod/recording.py
+++ b/nrv/fmod/_recording.py
@@ -1,15 +1,16 @@
 """
 NRV-:class:`.recorder` handling.
 """
+
 import faulthandler
 
 import numpy as np
 
-from ..backend.log_interface import rise_error, rise_warning
-from ..backend.MCore import MCH, synchronize_processes
-from ..backend.NRV_Class import NRV_class, is_empty_iterable
-from ..utils.units import cm, m
-from .materials import load_material
+from ..backend._log_interface import rise_error, rise_warning
+from ..backend._MCore import MCH, synchronize_processes
+from ..backend._NRV_Class import NRV_class, is_empty_iterable
+from ..utils._units import cm, m
+from ._materials import load_material
 
 # enable faulthandler to ease "segmentation faults" debug
 faulthandler.enable()
diff --git a/nrv/nmod/__init__.py b/nrv/nmod/__init__.py
index c5b71f10..ae08e956 100644
--- a/nrv/nmod/__init__.py
+++ b/nrv/nmod/__init__.py
@@ -1,2 +1,74 @@
-""" NeuRon Virtualizer, large scale modeling of Peripheral Nervous System with random stimulation waveforms"""
-""" Nmod librairy for neural models"""
+""" NEURON Models - nmod: handles neural fiber models using the NEURON software.
+
+nmod contains all the code to describe the axonal fibers using .mod mechanisms
+with NEURON. This subpackage contains all primitives to describe:
+
+  - unmyelinated axons with different models of nonlinear conductances,
+  - myelinated axons with different models of nonlinear conductances,
+  - fascicles consisting in bundles of (potentiallymixed ) axons,
+  - nerves containing one or more fascicles.
+
+nmod also contains tools to automatically generate fascicles and nerves,
+with fiber repartition mimicking realistic anatomical observations.
+
+Classes describing fibers, fascicles and nerves are simulable, meaning they
+all have a `simulate` method that triggers the simulation. Only the top level
+structure of the simulated scenario has to be simulated by the user, nrv takes
+care of handling the simulation, potential combination with subpackages
+(such as nmod or eit for instance). Parallel computing is also handled
+internally.
+
+.. note::
+  for scientific details of how nmod works and an overview of the general
+  implementation, refer to the 'Scientific foundations' section of the
+  documentation.
+"""
+
+from ._axon_pop_generator import (
+    load_stat,
+    create_axon_population,
+    fill_area_with_axons,
+    axon_packer,
+    expand_pop,
+    remove_collision,
+    remove_outlier_axons,
+    get_circular_contour,
+    plot_population,
+    save_axon_population,
+    load_axon_population,
+)
+from ._axons import axon
+from ._unmyelinated import unmyelinated
+from ._myelinated import myelinated
+from ._fascicles import fascicle
+from ._nerve import nerve
+from . import results
+
+submodules = ["results"]
+
+classes = [
+    "axon",
+    "unmyelinated",
+    "myelinated",
+    "fascicle",
+    "nerve"]
+
+functions = [
+    "create_axon_population",
+    "plot_population",
+    "save_axon_population",
+    "load_axon_population",
+    "fill_area_with_axons",
+    "axon_packer",
+    "expand_pop",
+    "remove_collision",
+    "remove_outlier_axons",
+    "get_circular_contour",
+    "load_stat",
+]
+
+__all__ = []
+
+__all__ += submodules
+__all__ += classes
+__all__ += functions
diff --git a/nrv/nmod/axon_pop_generator.py b/nrv/nmod/_axon_pop_generator.py
similarity index 99%
rename from nrv/nmod/axon_pop_generator.py
rename to nrv/nmod/_axon_pop_generator.py
index 3ca3cef5..0cc7b21d 100644
--- a/nrv/nmod/axon_pop_generator.py
+++ b/nrv/nmod/_axon_pop_generator.py
@@ -12,7 +12,8 @@
 from scipy.optimize import curve_fit
 from scipy.stats import rv_continuous, gamma
 
-from ..backend.log_interface import pass_info, progression_popup, rise_warning
+from ..backend._log_interface import pass_info, progression_popup, rise_warning
+from ..backend._parameters import parameters
 
 # WARNING:
 # no prompt message for numpy division by zeros: handled in the code !!!
@@ -25,7 +26,7 @@
 faulthandler.enable()
 
 # get the built-in material librairy
-dir_path = os.environ["NRVPATH"] + "/_misc"
+dir_path = parameters.nrv_path + "/_misc"
 stat_library = os.listdir(dir_path + "/stats/")
 
 #################################################
diff --git a/nrv/nmod/axons.py b/nrv/nmod/_axons.py
similarity index 98%
rename from nrv/nmod/axons.py
rename to nrv/nmod/_axons.py
index 02489b6e..de7900d7 100644
--- a/nrv/nmod/axons.py
+++ b/nrv/nmod/_axons.py
@@ -1,6 +1,7 @@
 """
 NRV-:class:`.axon` handling.
 """
+
 import faulthandler
 import os
 import time
@@ -10,20 +11,21 @@
 import neuron
 import numpy as np
 
-from .results.axons_results import axon_results
-from ..backend.file_handler import json_dump
-from ..backend.log_interface import rise_error, rise_warning
-from ..backend.NRV_Simulable import NRV_simulable
-from ..fmod.electrodes import *
-from ..fmod.extracellular import *
-from ..fmod.recording import *
-from ..utils.units import sci_round
+from .results._axons_results import axon_results
+from ..backend._file_handler import json_dump
+from ..backend._log_interface import rise_error, rise_warning
+from ..backend._NRV_Simulable import NRV_simulable
+from ..backend._parameters import parameters
+from ..fmod._electrodes import *
+from ..fmod._extracellular import *
+from ..fmod._recording import *
+from ..utils._units import sci_round
 
 # enable faulthandler to ease "segmentation faults" debug
 faulthandler.enable()
 
 # instructions for Neuron, find mod files and hide GUI
-dir_path = os.environ["NRVPATH"] + "/_misc"
+dir_path = parameters.nrv_path + "/_misc"
 neuron.load_mechanisms(dir_path + "/mods")
 neuron.h.load_file("stdrun.hoc")
 
@@ -42,6 +44,7 @@
     "Gaines_sensory",
 ]
 
+
 ##############################
 ## Usefull Neuron functions ##
 ##############################
@@ -451,23 +454,26 @@ def load_axon(
         rise_warning("load_axon is a deprecated method use load")
         self.save(data, extracel_context, intracel_context, rec_context)
 
-    def plot(self, axes: plt.axes, color: str="blue", elec_color="gold", **kwgs) -> None:
+    def plot(
+        self, axes: plt.axes, color: str = "blue", elec_color="gold", **kwgs
+    ) -> None:
 
         alpha = 1
         if "alpha" in kwgs:
             alpha = kwgs["alpha"]
 
-        axes.add_patch(plt.Circle(
-            (self.y, self.z),
-            self.d / 2,
-            color=color,
-            fill=True,
-            alpha = alpha,
-        ))
+        axes.add_patch(
+            plt.Circle(
+                (self.y, self.z),
+                self.d / 2,
+                color=color,
+                fill=True,
+                alpha=alpha,
+            )
+        )
         if self.extra_stim is not None:
             self.extra_stim.plot(axes=axes, color=elec_color, nerve_d=self.d)
 
-
     def __define_shape(self):
         """
         Define the shape of the axon after all sections creation
@@ -601,7 +607,7 @@ def shut_recorder_down(self):
     def simulate(
         self,
         **kwargs,
-    )->axon_results:
+    ) -> axon_results:
         """
         Simulates the axon using neuron framework
 
diff --git a/nrv/nmod/fascicles.py b/nrv/nmod/_fascicles.py
similarity index 90%
rename from nrv/nmod/fascicles.py
rename to nrv/nmod/_fascicles.py
index 5f620cd2..6e30e432 100644
--- a/nrv/nmod/fascicles.py
+++ b/nrv/nmod/_fascicles.py
@@ -1,26 +1,27 @@
 """
 NRV-:class:`.fascicle` handling.
 """
+
 import faulthandler
 import os
 
 import matplotlib.pyplot as plt
 import numpy as np
 
-from ..backend.file_handler import *
-from ..backend.log_interface import pass_info, rise_warning, pbar
-from ..backend.MCore import MCH, synchronize_processes
-from ..backend.NRV_Simulable import NRV_simulable, sim_results
-from ..fmod.extracellular import *
-from ..fmod.recording import *
-from ..utils.cell.CL_postprocessing import *
-from ..backend.inouts import check_function_kwargs
-from .axons import *
-from .axon_pop_generator import *
-from .myelinated import *
-from .unmyelinated import *
-from .results.fascicles_results import fascicle_results
-from .results.axons_results import axon_results
+from ..backend._file_handler import *
+from ..backend._log_interface import pass_info, rise_warning, pbar
+from ..backend._MCore import MCH, synchronize_processes
+from ..backend._NRV_Simulable import NRV_simulable, sim_results
+from ..fmod._extracellular import *
+from ..fmod._recording import *
+from ..ui._axon_postprocessing import *
+from ..backend._inouts import check_function_kwargs
+from ._axons import *
+from ._axon_pop_generator import *
+from ._myelinated import *
+from ._unmyelinated import *
+from .results._fascicles_results import fascicle_results
+from .results._axons_results import axon_results
 
 
 # Parallel computing options
@@ -78,11 +79,7 @@ class fascicle(NRV_simulable):
 
     See Also
     --------
-    :doc:`Simulables</usersguide/simulables>`: First optimization problem using NRV
-    
-    :class:`.nerve.nerve`
-    
-    :class:`.axons.axon`
+    :doc:`Simulables users guide</usersguide/simulables>`, :class:`Nerve-class<._nerve.nerve>`, :class:`Axon-class<._axons.axon>`
 
 
     .. rubric:: Customizable Attributes:
@@ -104,62 +101,62 @@ class fascicle(NRV_simulable):
          - ``float``
          - None
          - Length of the fascicle.
-       * 
+       *
          - ``D``
          - ``float``
          - None
          - Diameter of the fascicle.
-       * 
+       *
          - ``y_grav_center``
          - ``float``
          - 0
          - y-position of the fascicle center.
-       * 
+       *
          - ``z_grav_center``
          - ``float``
          - 0
          - z-position of the fascicle center.
-       * 
+       *
          - ``postproc_label``
          - ``str``
          - None
          - Label of the axon postprocessing funtion, used for the buildin postproc functions.
-       * 
+       *
          - ``postproc_function``
          - ``function``
          - None
          - Axon postprocessing funtion, used for the custom postproc functions.
-       * 
+       *
          - ``postproc_script``
          - ``str`` | ``function``
          - None
          - Either postprocessing funtion or postprocessing funtion label, automatically set depending on the type
-       * 
+       *
          - ``postproc_kwargs``
          - ``dict``
          - None
          - key arguments of the postporcessing function
-       * 
+       *
          - ``save_results``
          - ``bool``
          - False
          - If ``True``, fascicle configuration and all axon simulations results are saved in ``save_path`` directory.
-       * 
+       *
          - ``save_path``
          - ``str``
          - ""
          - Path of the directory where simulation results should be saved.
-       * 
+       *
          - ``return_parameters_only``
          - ``bool``
          - False
          - If ``True`` (and ``save_results`` also ``True``), only the parameters should be returned from the simulation.
-       * 
+       *
          - ``loaded_footprints``
          - ``bool``
          - False
          - If ``False``, the footprints already computed are favored over new footprint computation.
-       * 
+       *
          - ``verbose``
          - ``bool``
          - False
@@ -168,44 +165,13 @@ class fascicle(NRV_simulable):
 
     Note
     ----
-    Customizable Attributes can be either be set 
-
-
-
-    .. rubric:: Methods:
-
-    .. autosummary::
-
-        save
-        load
-        set_ID
-        define_length
-        define_circular_contour
-        get_circular_contour
-        fit_circular_contour
-        define_ellipsoid_contour
-        import_contour
-        fill_with_population
-        fit_population_to_size
-        translate_axons
-        translate_fascicle
-        rotate_axons
-        rotate_fascicle
-        set_axons_parameters
-        get_axons_parameters
-        remove_unmyelinated_axons
-        remove_myelinated_axons
-        remove_axons_size_threshold
-        plot
-        attach_extracellular_stimulation
-        remove_axons_electrode_overlap
-        change_stimulus_from_electrode
-        insert_I_Clamp
-        attach_extracellular_recorder
-        shut_recorder_down
-        generate_random_NoR_position
-        generate_ligned_NoR_position
-        simulate
+    Customizable attributes can either be set using :meth:`.fascicle.set_parameters` or simply by reafecting the value of the attribute.
+
+    Tip
+    ---
+    Additional simulation parameters can be changed using (:meth:`.fascicle.set_axons_parameters`, :meth:`.fascicle.change_stimulus_from_electrode`, ...).
+
+
 
     """
 
@@ -335,7 +301,9 @@ def save(
 
         bl += ["postproc_function", "postproc_script"]
         if self.postproc_label not in builtin_postproc_functions:
-            rise_warning("custom axon postprocessing cannot be save. Be carefull to set the postproc_function again when reloading fascicle")
+            rise_warning(
+                "custom axon postprocessing cannot be save. Be carefull to set the postproc_function again when reloading fascicle"
+            )
 
         if not intracel_context:
             bl += [
@@ -453,19 +421,19 @@ def N(self):
         """
         rise_warning(
             "DeprecationWarning: ",
-            "fascicle.N property is obsolete use fascicle.n_ax instead"
+            "fascicle.N property is obsolete use fascicle.n_ax instead",
         )
         return self.n_ax
 
     @property
     def A(self):
         """
-        Area of the fascicle 
+        Area of the fascicle
         """
-        if (self. D is None):
+        if self.D is None:
             return None
-        return (np.pi * (self.D / 2) ** 2)
-    
+        return np.pi * (self.D / 2) ** 2
+
     def set_ID(self, ID):
         """
         set the ID of the fascicle
@@ -545,7 +513,9 @@ def fit_circular_contour(self, y_c=None, z_c=None, Delta=0.1):
         Delta       : float
             distance between farest axon and contour, in um
         """
-        rise_warning("fit_circular_contour method usage is not recommended anymore and will be removed in future release.")
+        rise_warning(
+            "fit_circular_contour method usage is not recommended anymore and will be removed in future release."
+        )
         pass_info("Define fascicle size/shape at object creation instead.")
         N_axons = len(self.axons_diameter)
         D = 2 * Delta
@@ -614,7 +584,9 @@ def fill(
             optional, if specified, name file to store the population generated
         """
 
-        rise_warning("fill method usage is not recommended anymore and will be removed in future release.")
+        rise_warning(
+            "fill method usage is not recommended anymore and will be removed in future release."
+        )
         pass_info("Use axon_pop_generator methods instead.")
         #### AXON GENERATION: parallelization if resquested ####
         Area_to_fill = 0
@@ -662,7 +634,10 @@ def fill(
                 save_axon_population(
                     pop_fname, axons_diameter, axons_type, comment=None
                 )
-            axons_y, axons_z, = axon_packer(
+            (
+                axons_y,
+                axons_z,
+            ) = axon_packer(
                 axons_diameter,
                 delta=0.1,
                 y_gc=self.y_grav_center,
@@ -700,15 +675,23 @@ def fill(
             axons_z = None
             N = None
         ## BRODCASTING RESULTS TO ALL PARALLEL OBJECTS
-        self.axons_diameter = MCH.master_broadcasts_array_to_all(axons_diameter).flatten()
+        self.axons_diameter = MCH.master_broadcasts_array_to_all(
+            axons_diameter
+        ).flatten()
         self.axons_type = MCH.master_broadcasts_array_to_all(axons_type).flatten()
         self.axons_y = MCH.master_broadcasts_array_to_all(axons_y).flatten()
         self.axons_z = MCH.master_broadcasts_array_to_all(axons_z).flatten()
 
     def fill_with_population(
-        self, axons_diameter:np.array, axons_type:np.array, delta:float=1,
-        y_axons:np.array=None, z_axons:np.array=None, fit_to_size: bool = False, n_iter: int = 20_000
-    ) -> None: 
+        self,
+        axons_diameter: np.array,
+        axons_type: np.array,
+        delta: float = 1,
+        y_axons: np.array = None,
+        z_axons: np.array = None,
+        fit_to_size: bool = False,
+        n_iter: int = 20_000,
+    ) -> None:
         """
         Fill the fascicle with an axon population
 
@@ -734,22 +717,28 @@ def fill_with_population(
             N = len(axons_diameter)
             if (y_axons is None) and (z_axons is None):
                 y_axons, z_axons = axon_packer(
-                    axons_diameter,
-                    delta=delta,
-                    n_iter=n_iter
+                    axons_diameter, delta=delta, n_iter=n_iter
                 )
-            if (fit_to_size):
+            if fit_to_size:
                 if self.D is not None:
-                    d_pop = get_circular_contour(axons_diameter,y_axons,z_axons, delta)
+                    d_pop = get_circular_contour(
+                        axons_diameter, y_axons, z_axons, delta
+                    )
                     if (d_pop) < self.D:
-                        exp_factor = 0.99*(self.D/d_pop)
+                        exp_factor = 0.99 * (self.D / d_pop)
                         y_axons, z_axons = expand_pop(y_axons, z_axons, exp_factor)
                 else:
-                    rise_warning("Can't fit population to size, fascicle diameter is not defined.")
-            
-            axons_diameter, y_axons, z_axons, axons_type = remove_collision(axons_diameter, y_axons, z_axons, axons_type)
+                    rise_warning(
+                        "Can't fit population to size, fascicle diameter is not defined."
+                    )
+
+            axons_diameter, y_axons, z_axons, axons_type = remove_collision(
+                axons_diameter, y_axons, z_axons, axons_type
+            )
             if self.D is not None:
-                axons_diameter, y_axons, z_axons, axons_type = remove_outlier_axons(axons_diameter, y_axons, z_axons, axons_type, self.D-delta)
+                axons_diameter, y_axons, z_axons, axons_type = remove_outlier_axons(
+                    axons_diameter, y_axons, z_axons, axons_type, self.D - delta
+                )
         else:
             axons_diameter = None
             axons_type = None
@@ -757,11 +746,13 @@ def fill_with_population(
             z_axons = None
             N = None
         ## BRODCASTING RESULTS TO ALL PARALLEL OBJECTS
-        self.axons_diameter = MCH.master_broadcasts_array_to_all(axons_diameter).flatten()
+        self.axons_diameter = MCH.master_broadcasts_array_to_all(
+            axons_diameter
+        ).flatten()
         self.axons_type = MCH.master_broadcasts_array_to_all(axons_type).flatten()
         self.axons_y = MCH.master_broadcasts_array_to_all(y_axons).flatten()
         self.axons_z = MCH.master_broadcasts_array_to_all(z_axons).flatten()
-        self.translate_axons(self.y_grav_center,self.z_grav_center)
+        self.translate_axons(self.y_grav_center, self.z_grav_center)
 
     def fit_population_to_size(self, delta: float = 1):
         """
@@ -772,15 +763,19 @@ def fit_population_to_size(self, delta: float = 1):
         delta   : float
             minimum axon to fascicle border distance, in um
         """
-        self.translate_axons(-self.y_grav_center,-self.z_grav_center)
-        d_pop = get_circular_contour(self.axons_diameter,self.axons_y,self.axons_z, delta)
+        self.translate_axons(-self.y_grav_center, -self.z_grav_center)
+        d_pop = get_circular_contour(
+            self.axons_diameter, self.axons_y, self.axons_z, delta
+        )
         if (d_pop) < self.D:
-            exp_factor = 0.99*(self.D/d_pop)
-            self.axons_y, self.axons_z = expand_pop(self.axons_y, self.axons_z, exp_factor)
-        self.translate_axons(self.y_grav_center,self.z_grav_center)
+            exp_factor = 0.99 * (self.D / d_pop)
+            self.axons_y, self.axons_z = expand_pop(
+                self.axons_y, self.axons_z, exp_factor
+            )
+        self.translate_axons(self.y_grav_center, self.z_grav_center)
 
     ## Move methods
-    def translate_axons(self, y, z): 
+    def translate_axons(self, y, z):
         """
         Move axons only in a fascicle by group translation
 
@@ -954,7 +949,13 @@ def remove_axons_size_threshold(self, d, min=True):
 
     ## Representation methods
     def plot(
-        self, axes, contour_color="k", myel_color="r", unmyel_color="b", elec_color="gold", num=False
+        self,
+        axes,
+        contour_color="k",
+        myel_color="r",
+        unmyel_color="b",
+        elec_color="gold",
+        num=False,
     ):
         """
         plot the fascicle in the Y-Z plane (transverse section)
@@ -974,13 +975,15 @@ def plot(
         """
         if MCH.do_master_only_work():
             ## plot contour
-            axes.add_patch(plt.Circle(
-                (self.y_grav_center, self.z_grav_center),
-                self.D/2,
-                color=contour_color,
-                fill=False,
-                linewidth=2,
-            ))
+            axes.add_patch(
+                plt.Circle(
+                    (self.y_grav_center, self.z_grav_center),
+                    self.D / 2,
+                    color=contour_color,
+                    fill=False,
+                    linewidth=2,
+                )
+            )
             ## plot axons
             circles = []
             for k in range(self.n_ax):
@@ -1009,12 +1012,10 @@ def plot(
             if num:
                 for k in range(self.n_ax):
                     axes.text(self.axons_y[k], self.axons_z[k], str(k))
-            axes.set_xlim((-1.1*self.D/2, 1.1*self.D/2))
-            axes.set_ylim((-1.1*self.D/2, 1.1*self.D/2))
+            axes.set_xlim((-1.1 * self.D / 2, 1.1 * self.D / 2))
+            axes.set_ylim((-1.1 * self.D / 2, 1.1 * self.D / 2))
 
-    def plot_x(
-        self, axes, myel_color="r", unmyel_color="b", Myelinated_model="MRG"
-    ):
+    def plot_x(self, axes, myel_color="r", unmyel_color="b", Myelinated_model="MRG"):
         """
         plot the fascicle's axons along Xline (longitudinal)
 
@@ -1070,7 +1071,9 @@ def plot_x(
                     for electrode in self.extra_stim.electrodes:
                         if not is_FEM_electrode(electrode):
                             axes.plot(
-                                electrode.x * np.ones(2), [0, self.n_ax - 1], color="gold"
+                                electrode.x * np.ones(2),
+                                [0, self.n_ax - 1],
+                                color="gold",
                             )
                 axes.set_xlabel("x (um)")
                 axes.set_ylabel("axon ID")
@@ -1195,7 +1198,7 @@ def insert_I_Clamp(self, position, t_start, duration, amplitude, ax_list=None):
         self.N_intra += 1
 
     ## RECORDING MECHANIMS
-    def attach_extracellular_recorder(self, rec:recorder):
+    def attach_extracellular_recorder(self, rec: recorder):
         """
         attach an extracellular recorder to the axon
 
@@ -1336,7 +1339,7 @@ def get_electrodes_footprints_on_axons(
 
     def __init_axon_postprocessing(self):
         """
-            Internal use only: initialize the axon on-the-fly postprocessing.
+        Internal use only: initialize the axon on-the-fly postprocessing.
         """
         # Set the axon postprocessing label and function
         # self.postproc_script, self.postproc_function or self.postproc_label should have been set by self.set_parameters
@@ -1353,13 +1356,24 @@ def __init_axon_postprocessing(self):
             if self.postproc_label in globals():
                 self.postproc_function = globals()[self.postproc_label]
             else:
-                if isinstance(self.postproc_label,str):
+                if isinstance(self.postproc_label, str):
                     self.postproc_label = self.postproc_label.lower()
                 if self.postproc_label in deprecated_builtin_postproc_functions:
-                    rise_warning(DeprecationWarning, self.postproc_label," is a deprecated, use", deprecated_builtin_postproc_functions[self.postproc_label], "instead")
-                    self.postproc_label = deprecated_builtin_postproc_functions[self.postproc_label]
+                    rise_warning(
+                        DeprecationWarning,
+                        self.postproc_label,
+                        " is a deprecated, use",
+                        deprecated_builtin_postproc_functions[self.postproc_label],
+                        "instead",
+                    )
+                    self.postproc_label = deprecated_builtin_postproc_functions[
+                        self.postproc_label
+                    ]
                 elif self.postproc_label not in builtin_postproc_functions:
-                    rise_warning(self.postproc_label," isn't a buitin function, default post processing will be used instead")
+                    rise_warning(
+                        self.postproc_label,
+                        " isn't a buitin function, default post processing will be used instead",
+                    )
                     self.postproc_label = "default"
                 self.postproc_function = builtin_postproc_functions[self.postproc_label]
 
@@ -1370,7 +1384,9 @@ def __init_axon_postprocessing(self):
         if "fdir" not in self.postproc_kwargs.keys():
             self.postproc_kwargs["fdir"] = self.save_path + "Fascicle_" + str(self.ID)
         ##  ##
-        self.postproc_kwargs = check_function_kwargs(self.postproc_function, self.postproc_kwargs)
+        self.postproc_kwargs = check_function_kwargs(
+            self.postproc_function, self.postproc_kwargs
+        )
 
     def __sim_axon(
         self,
@@ -1378,7 +1394,7 @@ def __sim_axon(
         folder_name,
         is_master_slave=False,
         **kwargs,
-    )->axon_results:
+    ) -> axon_results:
         """
         Internal use only simumlated one axon of the fascicle
 
@@ -1499,15 +1515,15 @@ def __sim_axon(
 
         axon_sim = self.postproc_function(axon_sim, **self.postproc_kwargs)
         if self.save_results:
-                ax_fname = "sim_axon_" + str(k) + ".json"
-                axon_sim.save(save=True, fname=folder_name + "/" + ax_fname)
+            ax_fname = "sim_axon_" + str(k) + ".json"
+            axon_sim.save(save=True, fname=folder_name + "/" + ax_fname)
         return axon_sim
 
     def simulate(
         self,
         save_V_mem=False,
         **kwargs,
-    )->fascicle_results:
+    ) -> fascicle_results:
         """
         Simulates the fascicle using neuron framework. Parallel computing friendly. Does not return
         results (possibly too large in memory and complex with parallel computing), but instead
@@ -1563,7 +1579,7 @@ def simulate(
         """
         fasc_sim = super().simulate(**kwargs)
         if not MCH.do_master_only_work():
-            fasc_sim = sim_results({"dummy_res":1})
+            fasc_sim = sim_results({"dummy_res": 1})
         # disable the result storage only if results are fully return
         # To use with caution (mostly for optimisation)
         if not self.save_results:
@@ -1580,11 +1596,13 @@ def simulate(
             self.generate_random_NoR_position()
         # create folder and save fascicle config
         folder_name = self.save_path + "Fascicle_" + str(self.ID)
-        if len(self.save_path) and MCH.do_master_only_work():          #LR: Force folder creation if any save_path is specified --> usefull for some PP functions (ex: scatter_plot)
+        if (
+            len(self.save_path) and MCH.do_master_only_work()
+        ):  # LR: Force folder creation if any save_path is specified --> usefull for some PP functions (ex: scatter_plot)
             create_folder(folder_name)
 
         if MCH.do_master_only_work() and self.save_results:
-            #create_folder(folder_name)
+            # create_folder(folder_name)
             self.config_filename = folder_name + "/00_Fascicle_config.json"
             fasc_sim.save(save=True, fname=self.config_filename)
         else:
@@ -1674,11 +1692,10 @@ def simulate(
                 ## SLAVES ##
                 try:
                     for k in this_core_mask:
-                        axon_sim = self.__sim_axon(k, folder_name,is_master_slave)
+                        axon_sim = self.__sim_axon(k, folder_name, is_master_slave)
                         if not self.return_parameters_only:
                             fasc_sim.update({"axon" + str(k): axon_sim})
 
-
                     data = {"rank": MCH.rank, "status": "success"}
                     MCH.send_data_to_master(data)
                 except KeyboardInterrupt:
@@ -1725,9 +1742,18 @@ def simulate(
             fasc_sim = MCH.gather_jobs(fasc_sim)
             if MCH.do_master_only_work():
                 if "extra_stim" in fasc_sim:
-                    fasc_sim['extra_stim'] = load_any(fasc_sim['extra_stim']) #dirty hack to force NRV_class instead of dict
+                    fasc_sim["extra_stim"] = load_any(
+                        fasc_sim["extra_stim"]
+                    )  # dirty hack to force NRV_class instead of dict
                 if self.record:
-                    fasc_sim['recorder'] = load_any(fasc_sim['recorder'])   #idem
+                    fasc_sim["recorder"] = load_any(fasc_sim["recorder"])
+                # Remove the "dummy_res" key from results in the master and add to the other process
+                # see if can improve (by not generating the dummy_res at the beginning of simulate)
+                if "dummy_res" in fasc_sim:
+                    fasc_sim.pop("dummy_res")
+            else:
+                #
+                fasc_sim = fascicle_results({"dummy_res": 1})# idem
         if MCH.is_alone() and self.verbose:
             pass_info("... Simulation done")
             fasc_sim["is_simulated"] = True
diff --git a/nrv/nmod/myelinated.py b/nrv/nmod/_myelinated.py
similarity index 98%
rename from nrv/nmod/myelinated.py
rename to nrv/nmod/_myelinated.py
index 7fb06a80..77923835 100644
--- a/nrv/nmod/myelinated.py
+++ b/nrv/nmod/_myelinated.py
@@ -1,14 +1,15 @@
 """
 NRV-:class:`.myelinated` handling.
 """
+
 import math
 
 import numpy as np
 
-from ..backend.log_interface import rise_warning
-from ..backend.NRV_Class import is_empty_iterable
-from .axons import *
-from ..utils.misc import nearest_idx
+from ..backend._log_interface import rise_warning
+from ..backend._NRV_Class import is_empty_iterable
+from ._axons import *
+from ..utils._misc import nearest_idx
 
 MRG_fiberD = np.asarray([1, 2, 5.7, 7.3, 8.7, 10.0, 11.5, 12.8, 14.0, 15.0, 16.0])
 MRG_g = np.asarray(
@@ -63,11 +64,11 @@ def get_MRG_parameters(diameter):
         nodeD_poly = np.poly1d(np.polyfit(MRG_fiberD, MRG_nodeD, 3))
         paraD1_poly = np.poly1d(np.polyfit(MRG_fiberD, MRG_paraD1, 3))
         paraD2_poly = np.poly1d(np.polyfit(MRG_fiberD, MRG_paraD2, 3))
-        
+
         if diameter < 1.0 or diameter > 14.0:
             # outside of the MRG originla limit, take 1st order approx,
             paralength2_poly = np.poly1d(np.polyfit(MRG_fiberD, MRG_paralength2, 3))
-            deltax_poly = np.poly1d(np.polyfit(MRG_fiberD, MRG_deltax, 2))        
+            deltax_poly = np.poly1d(np.polyfit(MRG_fiberD, MRG_deltax, 2))
         else:
             # try to fit a bit better
             paralength2_poly = np.poly1d(np.polyfit(MRG_fiberD, MRG_paralength2, 5))
@@ -603,19 +604,28 @@ def save(
             blacklist=blacklist,
         )
 
-    def plot(self, axes: plt.axes, color: str="red", node_color: str="lightgray", elec_color="gold", **kwgs) -> None:
-        super().plot(axes, color, elec_color,**kwgs)
+    def plot(
+        self,
+        axes: plt.axes,
+        color: str = "red",
+        node_color: str = "lightgray",
+        elec_color="gold",
+        **kwgs,
+    ) -> None:
+        super().plot(axes, color, elec_color, **kwgs)
         alpha = 1
         if "alpha" in kwgs:
             alpha = kwgs["alpha"]
 
-        axes.add_patch(plt.Circle(
-            (self.y, self.z),
-            self.nodeD / 2,
-            fc=node_color,
-            fill=True,
-            alpha = alpha,
-        ))
+        axes.add_patch(
+            plt.Circle(
+                (self.y, self.z),
+                self.nodeD / 2,
+                fc=node_color,
+                fill=True,
+                alpha=alpha,
+            )
+        )
 
     def __set_model(self, model):
         """
@@ -865,7 +875,7 @@ def __get_seg_positions(self):
         x_nodes = []
         nodes_index = []
         self.rec_position_list = []
-        #print(self.axon_path_type)
+        # print(self.axon_path_type)
         for k in range(len(self.axon_path_type)):
             sec_type = self.axon_path_type[k]
             sec_index = self.axon_path_index[k]
@@ -919,11 +929,11 @@ def __get_seg_positions(self):
                 x_offset += self.STIN[sec_index].L
         self.x = np.asarray(x)
         self.x_nodes = np.asarray(x_nodes)
-        #self.node_index = np.asarray(nodes_index)
+        # self.node_index = np.asarray(nodes_index)
 
-        self.node_index = [nearest_idx(self.x, x_n) for x_n in x_nodes]         #LR: to avoid duplicates in node_index calculated previously...
-        
-        
+        self.node_index = [
+            nearest_idx(self.x, x_n) for x_n in x_nodes
+        ]  # LR: to avoid duplicates in node_index calculated previously...
 
     def __get_rec_positions(self):
         """
diff --git a/nrv/nmod/nerve.py b/nrv/nmod/_nerve.py
similarity index 82%
rename from nrv/nmod/nerve.py
rename to nrv/nmod/_nerve.py
index 86d5b2d4..a51b7b8e 100644
--- a/nrv/nmod/nerve.py
+++ b/nrv/nmod/_nerve.py
@@ -1,21 +1,22 @@
 """
 NRV-:class:`.nerve` handling.
 """
+
 import numpy as np
 
-from ..backend.log_interface import pass_info, rise_warning
-from ..backend.NRV_Class import load_any
-from ..backend.NRV_Simulable import NRV_simulable
-from ..fmod.stimulus import stimulus
-from .fascicles import *
-from .results.nerve_results import nerve_results
+from ..backend._log_interface import pass_info, rise_warning
+from ..backend._NRV_Class import load_any
+from ..backend._NRV_Simulable import NRV_simulable
+from ..utils._stimulus import stimulus
+from ._fascicles import *
+from .results._nerve_results import nerve_results
 
 
 #################
 ## Nerve class ##
 #################
 class nerve(NRV_simulable):
-    """
+    r"""
     A nerve in NRV is defined as:
         - a list of :class:`.fascicle`
         - an `analytical` :class:`~nrv.fmod.extracellular.stimulation` or a :class:`~nrv.fmod.extracellular.FEM_stimulation` context
@@ -25,6 +26,99 @@ class nerve(NRV_simulable):
     The extracellular context of the nerve is automatically generated from the context of its
     fascicles and an optional context added directly to the nerve.
 
+    See Also
+    --------
+    :doc:`Simulables users guide</usersguide/simulables>`, :class:`Fascicle-class<._fascicles.fascicle>`, :class:`Axon-class<._axons.axon>`
+
+
+    .. rubric:: Customizable Attributes:
+
+    .. list-table::
+       :widths: 10 10 10 70
+       :header-rows: 1
+
+       * - Attributes
+         - Type
+         - Default
+         - Description
+       * - ``ID``
+         - ``int``
+         - 0
+         - Identification number of the nerve.
+       *
+         - ``L``
+         - ``float``
+         - None
+         - Length of the nerve.
+       *
+         - ``D``
+         - ``float``
+         - None
+         - Diameter of the nerve.
+       *
+         - ``y_grav_center``
+         - ``float``
+         - 0
+         - y-position of the nerve center.
+       *
+         - ``z_grav_center``
+         - ``float``
+         - 0
+         - z-position of the nerve center.
+       *
+         - ``postproc_label``
+         - ``str``
+         - None
+         - Label of the axon postprocessing funtion, used for the buildin postproc functions.
+       *
+         - ``postproc_function``
+         - ``function``
+         - None
+         - Axon postprocessing funtion, used for the custom postproc functions.
+       *
+         - ``postproc_script``
+         - ``str`` | ``function``
+         - None
+         - Either postprocessing funtion or postprocessing funtion label, automatically set depending on the type
+       *
+         - ``postproc_kwargs``
+         - ``dict``
+         - None
+         - key arguments of the postporcessing function
+       *
+         - ``save_results``
+         - ``bool``
+         - False
+         - If ``True``, nerve configuration and all axon simulations results are saved in ``save_path`` directory.
+       *
+         - ``save_path``
+         - ``str``
+         - ""
+         - Path of the directory where simulation results should be saved.
+       *
+         - ``return_parameters_only``
+         - ``bool``
+         - False
+         - If ``True`` (and ``save_results`` also ``True``), only the parameters should be returned from the simulation.
+       *
+         - ``loaded_footprints``
+         - ``bool``
+         - False
+         - If ``False``, the footprints already computed are favored over new footprint computation.
+       *
+         - ``verbose``
+         - ``bool``
+         - False
+         - Plot or not.
+
+    Note
+    ----
+    Customizable attributes can either be set using :meth:`nerve.set_parameters` or simply by reafecting the value of the attribute.
+
+    Tip
+    ---
+    Additional simulation parameters can be changed using (:meth:`.nerve.set_axons_parameters`, :meth:`.nerve.change_stimulus_from_electrode`, ...).
+
     Parameters
     ----------
     length              : float
@@ -34,7 +128,7 @@ class nerve(NRV_simulable):
     Outer_D            : float
         Outer saline box diameter, in mm
     ID        : int
-        Nerve unique identifier 
+        Nerve unique identifier
     """
 
     def __init__(self, length=10_000, diameter=100, Outer_D=5, ID=0, **kwargs):
@@ -57,7 +151,7 @@ def __init__(self, length=10_000, diameter=100, Outer_D=5, ID=0, **kwargs):
 
         self.type = "nerve"
         self.L = length
-        self.D =  None
+        self.D = None
         self.y_grav_center = 0
         self.z_grav_center = 0
         self.Outer_D = Outer_D
@@ -80,7 +174,7 @@ def __init__(self, length=10_000, diameter=100, Outer_D=5, ID=0, **kwargs):
             "dt": 0.001,
             "Nrec": 0,
             "Nsec": 1,
-            "Nseg_per_sec": length//25,
+            "Nseg_per_sec": length // 25,
             "freq": 100,
             "freq_min": 0,
             "mesh_shape": "plateau_sigmoid",
@@ -115,7 +209,7 @@ def __init__(self, length=10_000, diameter=100, Outer_D=5, ID=0, **kwargs):
         self.footprints = {}
         self.is_footprinted = False
         self.myelinated_nseg_per_sec = 3
-        self.unmyelinated_nseg = length//25
+        self.unmyelinated_nseg = length // 25
         # intra-cellular stimulation
         self.N_intra = 0
         self.intra_stim_position = []
@@ -129,10 +223,8 @@ def __init__(self, length=10_000, diameter=100, Outer_D=5, ID=0, **kwargs):
         self.is_simulated = False
         # Simulation status
 
-
         self.define_circular_contour(diameter)
 
-
     ## save/load methods
     def save(
         self,
@@ -174,7 +266,9 @@ def save(
 
         bl += ["postproc_function", "postproc_script"]
         if self.postproc_label not in builtin_postproc_functions:
-            rise_warning("custom axon postprocessing cannot be save. Be carefull to set the postproc_function again when reloading fascicle")
+            rise_warning(
+                "custom axon postprocessing cannot be save. Be carefull to set the postproc_function again when reloading fascicle"
+            )
 
         if not intracel_context:
             bl += [
@@ -269,9 +363,42 @@ def load(
     ## Nerve property method
     @property
     def n_fasc(self):
+        """
+        Number of fascicles in the nerves
+
+        Returns
+        -------
+        int
+            Number of fascicles.
+        """
         return len(self.fascicles)
+    
+    @property
+    def n_ax(self):
+        """
+        Number of axons in the nerves
+
+        Returns
+        -------
+        int
+            Number of axons.
+        """
+        return self.get_n_ax()
+
+    def get_n_ax(self, id_fasc:int|None=None)->int:
+        """
+        Returns the number of axons in a given fascicle or in all the nerve
+
+        Parameters
+        ----------
+        id_fasc : _type_, optional
+            ID of the fascicle from which the number of axons is returned; if None, number of all axons in the nerve is returned, by default None
 
-    def get_n_ax(self, id_fasc=None):
+        Returns
+        -------
+        int
+            Number of axons.
+        """
         n = 0
         if id_fasc is None:
             id_fasc = self.fascicles.keys()
@@ -282,7 +409,6 @@ def get_n_ax(self, id_fasc=None):
                 fasc = self.fascicles[i_fasc]
                 n += fasc.n_ax
         return n
-    n_ax = property(get_n_ax)
 
     def set_ID(self, ID):
         """
@@ -297,12 +423,12 @@ def set_ID(self, ID):
 
     def define_length(self, L):
         """
-        set the length over the x axis of the nerve
+        Set the length over the x axis of the nerve
 
         Parameters
         ----------
         L   : float
-            length of the nerve in um
+            length of the nerve in um.
         """
         if self.extra_stim is not None or self.N_intra > 0:
             rise_warning(
@@ -416,6 +542,19 @@ def import_contour(self, smthing_else):
 
     ## Fascicles handling methods
     def get_fascicles(self, ID_only=False):
+        """
+        Return a :class:`._fascicle.fascicle` object from it ID in the nerve
+
+        Parameters
+        ----------
+        ID_only : bool, optional
+            ID of the fascicle, by default False
+
+        Returns
+        -------
+        _type_
+            _description_
+        """
         if ID_only:
             return self.fascicles_IDs
         else:
@@ -462,7 +601,7 @@ def add_fascicle(self, fascicle, ID=None, y=None, z=None, **kwargs):
                 self.__merge_fascicular_context(self.fascicles[fasc.ID])
                 self.fascicles[fasc.ID].define_length(self.L)
 
-    def __check_fascicle_overlap(self, fasc:fascicle):
+    def __check_fascicle_overlap(self, fasc: fascicle):
         for fasc_i in self.fascicles.values():
             dist_yz = (fasc.y_grav_center - fasc_i.y_grav_center) ** 2 + (
                 fasc.z_grav_center - fasc_i.z_grav_center
@@ -547,7 +686,14 @@ def get_axons_parameters(self, unmyelinated_only=False, myelinated_only=False):
 
     ## Representation methods
     def plot(
-        self, axes:plt.axes, contour_color:str="k", myel_color:str="r", unmyel_color:str="b", elec_color:str="gold",num:bool=False, **kwgs
+        self,
+        axes: plt.axes,
+        contour_color: str = "k",
+        myel_color: str = "r",
+        unmyel_color: str = "b",
+        elec_color: str = "gold",
+        num: bool = False,
+        **kwgs,
     ):
         """
         plot the nerve in the Y-Z plane (transverse section)
@@ -569,13 +715,15 @@ def plot(
         """
         if MCH.do_master_only_work():
             ## plot contour
-            axes.add_patch(plt.Circle(
-                (self.y_grav_center, self.z_grav_center),
-                self.D/2,
-                color=contour_color,
-                fill=False,
-                linewidth=4,
-            ))
+            axes.add_patch(
+                plt.Circle(
+                    (self.y_grav_center, self.z_grav_center),
+                    self.D / 2,
+                    color=contour_color,
+                    fill=False,
+                    linewidth=4,
+                )
+            )
             for i in self.fascicles:
                 fasc = self.fascicles[i]
                 fasc.plot(
@@ -587,8 +735,8 @@ def plot(
                 )
             if self.extra_stim is not None:
                 self.extra_stim.plot(axes=axes, color=elec_color, nerve_d=self.D)
-            axes.set_xlim((-1.1*self.D/2, 1.1*self.D/2))
-            axes.set_ylim((-1.1*self.D/2, 1.1*self.D/2))
+            axes.set_xlim((-1.1 * self.D / 2, 1.1 * self.D / 2))
+            axes.set_ylim((-1.1 * self.D / 2, 1.1 * self.D / 2))
 
     ## Context handling methods
     def clear_context(
@@ -648,7 +796,7 @@ def insert_I_Clamp(self, position, t_start, duration, amplitude, ax_list=None):
         self.N_intra += 1
 
     # Extracellular
-    def attach_extracellular_stimulation(self, stimulation: FEM_stimulation):
+    def attach_extracellular_stimulation(self, stimulation): #: FEM_stimulation):
         """
         attach a extracellular context of simulation for an axon.
 
@@ -686,10 +834,11 @@ def attach_extracellular_stimulation(self, stimulation: FEM_stimulation):
             if _overlap == -1:
                 self.extra_stim.add_electrode(elec, stimulation.stimuli[i])
                 for fasc in self.fascicles.values():
-                        fasc.remove_axons_electrode_overlap(elec)
+                    fasc.remove_axons_electrode_overlap(elec)
             else:
-                rise_warning(f"Electrode {i} ovelerlap with the perineurium the fascicle {_overlap}")
-
+                rise_warning(
+                    f"Electrode {i} ovelerlap with the perineurium the fascicle {_overlap}"
+                )
 
     def change_stimulus_from_electrode(self, ID_elec, stimulus):
         """
@@ -707,7 +856,7 @@ def change_stimulus_from_electrode(self, ID_elec, stimulus):
         else:
             rise_warning("Cannot be changed: no extrastim in the nerve")
 
-    def __check_perineurium_electrode_overlap(self, electrode:electrode)->int:
+    def __check_perineurium_electrode_overlap(self, electrode: electrode) -> int:
         """
         Check if an electrode overlap with one fascicle perineurium of the nerve.
 
@@ -715,7 +864,7 @@ def __check_perineurium_electrode_overlap(self, electrode:electrode)->int:
         ---------
         electrode   : electrode
             electrode to check
-        
+
         Returns
         -------
         int
@@ -729,14 +878,13 @@ def __check_perineurium_electrode_overlap(self, electrode:electrode)->int:
             if is_LIFE_electrode(electrode):
                 D = electrode.D
             for fasc in self.fascicles.values():
-                dist = np.sqrt((fasc.y_grav_center - y) ** 2 + (fasc.z_grav_center - z) ** 2) - (
-                    fasc.D / 2
-                )
+                dist = np.sqrt(
+                    (fasc.y_grav_center - y) ** 2 + (fasc.z_grav_center - z) ** 2
+                ) - (fasc.D / 2)
                 if abs(dist) < D:
                     return fasc.ID
         return -1
 
-
     # RECORDING MECHANIMS
     def attach_extracellular_recorder(self, rec: recorder):
         """
@@ -789,7 +937,6 @@ def __set_fascicles_simulation_parameters(self):
             fasc.return_parameters_only = self.return_parameters_only
             fasc.verbose = self.verbose
 
-
     # Footprint and mesh
     def compute_electrodes_footprints(self, **kwargs):
         """
@@ -811,12 +958,11 @@ def compute_electrodes_footprints(self, **kwargs):
                     fasc.compute_electrodes_footprints()
             self.is_footprinted = True
 
-
     ## SIMULATION
     def simulate(
         self,
         **kwargs,
-    )->nerve_results:
+    ) -> nerve_results:
         """
         Simulate the nerve with the proposed extracellular context. Top level method for large
         scale neural simulation.
@@ -834,9 +980,11 @@ def simulate(
         nerve_sim = super().simulate(**kwargs)
         self.__set_fascicles_simulation_parameters()
         if not MCH.do_master_only_work():
-            nerve_sim = nerve_results({"dummy_res":1})
-        
-        if self.save_path:                                                          #LR: Force folder creation if any save_path is specified --> usefull for some PP functions (ex: scatter_plot)
+            nerve_sim = nerve_results({"dummy_res": 1})
+
+        if (
+            self.save_path
+        ):  # LR: Force folder creation if any save_path is specified --> usefull for some PP functions (ex: scatter_plot)
             folder_name = self.save_path + "Nerve_" + str(self.ID) + "/"
             if MCH.do_master_only_work():
                 create_folder(folder_name)
@@ -867,16 +1015,17 @@ def simulate(
                 i_pbar += 1
                 fasc_kwargs["pbar"] = _pbar
             nerve_sim["fascicle" + str(fasc.ID)] = fasc.simulate(
-                in_nerve=True, **fasc_kwargs,
+                in_nerve=True,
+                **fasc_kwargs,
             )
         if has_pbar:
             del _pbar
         if self.verbose:
             pass_info("...Done!")
-        #dirty hack to force NRV_class type when saved
+        # dirty hack to force NRV_class type when saved
         if "extra_stim" in nerve_sim:
             nerve_sim["extra_stim"] = load_any(nerve_sim["extra_stim"])
-        if self.record:     # recorder not saved in result !!BUG
+        if self.record:  # recorder not saved in result !!BUG
             nerve_sim["recorder"] = self.recorder
         self.is_simulated = True
         return nerve_sim
diff --git a/nrv/nmod/unmyelinated.py b/nrv/nmod/_unmyelinated.py
similarity index 99%
rename from nrv/nmod/unmyelinated.py
rename to nrv/nmod/_unmyelinated.py
index b50cc8f1..bc37d3e2 100644
--- a/nrv/nmod/unmyelinated.py
+++ b/nrv/nmod/_unmyelinated.py
@@ -1,12 +1,13 @@
 """
 NRV-:class:`.unmyelinated` handling.
 """
+
 import math
 
 import numpy as np
 
-from .axons import *
-from ..backend.NRV_Class import is_empty_iterable
+from ._axons import axon, neuron, unmyelinated_models, create_Nseg_freq_shape, d_lambda_rule
+from ..backend._NRV_Class import is_empty_iterable
 
 
 class unmyelinated(axon):
diff --git a/nrv/nmod/results/__init__.py b/nrv/nmod/results/__init__.py
index dc25684b..eb20f1ba 100644
--- a/nrv/nmod/results/__init__.py
+++ b/nrv/nmod/results/__init__.py
@@ -1,1 +1,33 @@
-""" NRV-Nmod-Results librairy for neural models"""
+""" nmod Results: standardized result gathering for nmod simulations.
+
+nmod.results defines classes to gather results from nmod object simulations.
+Result classes are defined for axons (myelinated and unlyelinated), fascicles
+and nerves. All computed values, state variables and electrical quantities are
+stored and exportable as dictionaries (json format).
+
+"""
+
+from ._axons_results import axon_results
+from ._unmyelinated_results import unmyelinated_results
+from ._myelinated_results import myelinated_results
+from ._fascicles_results import fascicle_results
+from ._nerve_results import nerve_results
+
+
+submodules = []
+
+classes = [
+    "axon_results",
+    "unmyelinated_results",
+    "myelinated_results",
+    "fascicle_results",
+    "nerve_results",
+]
+
+functions = []
+
+__all__ = []
+
+__all__ += submodules
+__all__ += classes
+__all__ += functions
diff --git a/nrv/nmod/results/axons_results.py b/nrv/nmod/results/_axons_results.py
similarity index 64%
rename from nrv/nmod/results/axons_results.py
rename to nrv/nmod/results/_axons_results.py
index e82558d8..0aafbf49 100644
--- a/nrv/nmod/results/axons_results.py
+++ b/nrv/nmod/results/_axons_results.py
@@ -7,19 +7,23 @@
 from itertools import combinations
 import matplotlib.pyplot as plt
 from copy import deepcopy
+from scipy.signal import find_peaks
+
+from ...fmod.FEM.fenics_utils._f_materials import f_material, mat_from_interp
+from ...backend._NRV_Results import sim_results
+from ...backend._file_handler import json_dump
+from ...backend._log_interface import rise_warning, rise_error
+from ...utils._units import to_nrv_unit, from_nrv_unit, convert, nm
+from ...utils._misc import (
+    distance_point2line,
+    membrane_capacitance_from_model,
+    compute_complex_admitance,
+    nearest_greater_idx,
+)
 
-from ...fmod.FEM.fenics_utils.f_materials import f_material, mat_from_interp
-from ...backend.NRV_Results import sim_results
-from ...backend.file_handler import json_dump
-from ...backend.log_interface import rise_warning, rise_error
-from ...utils.units import to_nrv_unit, from_nrv_unit, convert, nm
-from ...utils.misc import distance_point2line, membrane_capacitance_from_model, compute_complex_admitance,nearest_greater_idx
 
 def max_spike_position(blocked_spike_positionlist, position_max, spike_begin="down"):
-    rise_warning(
-        "DeprecationWarning: ",
-        "max_spike_position is obsolete"
-    )
+    rise_warning("DeprecationWarning: ", "max_spike_position is obsolete")
     if spike_begin == "down":
         while blocked_spike_positionlist[
             position_max + 1
@@ -37,6 +41,7 @@ def max_spike_position(blocked_spike_positionlist, position_max, spike_begin="do
             position_max = position_max + 1
         return position_max
 
+
 def AP_detection(
     Voltage, t, x, list_to_parse, thr, dt, t_start, t_stop, t_refractory, t_min_spike
 ):
@@ -44,10 +49,7 @@ def AP_detection(
     Internal use only, detects an AP
     """
 
-    rise_warning(
-        "DeprecationWarning: ",
-        "AP_detection is obsolete"
-    )
+    rise_warning("DeprecationWarning: ", "AP_detection is obsolete")
     raster_position = []
     raster_x_position = []
     raster_time_index = []
@@ -79,16 +81,13 @@ def AP_detection(
     )
 
 
-#@jit(nopython=True, fastmath=True)
+# @jit(nopython=True, fastmath=True)
 def count_spike(onset_position):
     """
     spike counting, just in time compiled. For internal use only.
     """
 
-    rise_warning(
-        "DeprecationWarning: ",
-        "AP_detection is obsolete"
-    )
+    rise_warning("DeprecationWarning: ", "AP_detection is obsolete")
     if len(onset_position) == 0:
         spike_number = 0
         return 0
@@ -100,8 +99,17 @@ def count_spike(onset_position):
                     spike_number = spike_number + 1
     return spike_number
 
-def rasterize(y_data: np.array, x_data: np.array, t_data: np.array,threshold: np.float64,
-              t_min_AP = 0.1, t_refractory = 0.5,t_start: np.float64 = None, t_stop: np.float64 = None) -> np.array:
+
+def rasterize(
+    y_data: np.array,
+    x_data: np.array,
+    t_data: np.array,
+    threshold: np.float64,
+    t_min_AP=0.1,
+    t_refractory=0.5,
+    t_start: np.float64 = None,
+    t_stop: np.float64 = None,
+) -> np.array:
     """
     Rasterize a membrane potential (or filtered or any quantity processed from membrane voltage), with AP detection.
 
@@ -126,55 +134,48 @@ def rasterize(y_data: np.array, x_data: np.array, t_data: np.array,threshold: np
     """
 
     if t_start is not None:
-        t_start_idx = np.where(t_data>=t_start)[0][0]
+        t_start_idx = np.where(t_data >= t_start)[0][0]
     else:
         t_start_idx = 0
 
     if t_stop is not None:
-        t_stop_idx = np.where(t_data<=t_stop)[0][0]
+        t_stop_idx = np.where(t_data <= t_stop)[0][0]
     else:
         t_stop_idx = -1
 
-    t_ap = np.array([],np.int32)
-    x_idx_AP = np.array([],np.int32)
-
-    for x_val,v in enumerate(y_data):
-        v = v[t_start_idx:t_stop_idx]
-        th_idx = np.where(v >= threshold)[0]                 #find vmem above threshold
-        if (len(th_idx)):
-            end_cons_idx = np.where(np.diff(th_idx) != 1)[0]     #find when indexes are not consecutive (ie multiple APs) @Warning: might not work when AP "jumps" above nodes
-            start_APs_idx = th_idx[end_cons_idx+1]               #get start index of each APs
-            end_APs_idx = th_idx[end_cons_idx]                   #get stop index of each APs
+    t_idx_AP = np.array([], np.int32)
+    x_idx_AP = np.array([], np.int32)
 
-            start_APs_idx = np.concatenate([[th_idx[0]],start_APs_idx])  #add index 0 for start idxs
-            end_APs_idx = np.concatenate([end_APs_idx,[th_idx[-1]]])     #add index -1 in stop idxs
-            dur_APs = t_data[end_APs_idx] - t_data[start_APs_idx]           #get duration of each APs
-            dur_inter_APs = t_data[np.diff(start_APs_idx)]                  #get inter APs duration
+    dt = t_data[1]-t_data[0]
+    dis = int(t_refractory/dt)
+    width = int(t_min_AP/dt)
+    #width = None
+    height = [-20,70]     #min/max heigh of AP
 
-            AP_mask = np.where(dur_APs<t_min_AP)[0]                         #mask when AP duration is too small
-            AP_mask2 = np.where(dur_inter_APs<t_refractory)[0]+1            #mask when inter APs duration is too small
-            AP_mask = np.concatenate([AP_mask,AP_mask2])
-
-            start_APs_idx = np.delete(start_APs_idx,AP_mask)
-            end_APs_idx = np.delete(end_APs_idx,AP_mask)
-            dur_APs= np.delete(dur_APs,AP_mask)
-
-            t_ap = np.concatenate([t_ap,start_APs_idx])
-            x_idx_AP = np.concatenate([x_idx_AP,np.ones(np.size(start_APs_idx))*x_val])
+    for x_val, v in enumerate(y_data):
+        data = v[t_start_idx:t_stop_idx]
+        peak_idxs, _ = find_peaks(data, height=height,distance=dis, width=width)
+        t_idx_AP = np.concatenate([t_idx_AP, peak_idxs])
+        x_idx_AP = np.concatenate([x_idx_AP, np.ones(np.size(peak_idxs)) * x_val])
         
-    t_ap = np.int32(t_ap)
+    t_idx_AP = np.int32(t_idx_AP)
     x_idx_AP = np.int32(x_idx_AP)
 
-    if len(t_data) > 5:
-        return(x_idx_AP,x_data[x_idx_AP],t_ap,t_data[t_ap])
+    if len(t_data) :
+        return (x_idx_AP, x_data[x_idx_AP], t_idx_AP, t_data[t_idx_AP])
     else:
-        return([],[],[],[])
+        return ([], [], [], [])
 
 
-def get_first_AP(x_APs: np.array, x_idx_APs: np.array, t_APs: np.array,
-                 t_idx_APs: np.array, t_refract: np.float64 = .5) -> NDArray|NDArray|NDArray:
+def get_first_AP(
+    x_APs: np.array,
+    x_idx_APs: np.array,
+    t_APs: np.array,
+    t_idx_APs: np.array,
+    t_refract: np.float64 = 0.5,
+) -> NDArray | NDArray | NDArray:
     """
-    Extract time and position of the first rasterized AP 
+    Extract time and position of the first rasterized AP
 
     Parameters
     ----------
@@ -203,93 +204,113 @@ def get_first_AP(x_APs: np.array, x_idx_APs: np.array, t_APs: np.array,
         index position of the AP
     """
 
-    if (len(t_APs)==1):
-        return(np.array(x_APs),[0],np.array(t_APs),[0],[0])
-        
-    if (len(t_APs)<1):
-        return([],[],[],[],[])
-    
-    ordered_t_idx = np.argsort(t_APs)               #sort time indexes 
+    if len(t_APs) == 1:
+        return (np.array(x_APs), [0], np.array(t_APs), [0], [0])
+
+    if len(t_APs) < 1:
+        return ([], [], [], [], [])
 
-    x_ordered = x_APs[ordered_t_idx]                #sort x positions accordingly
-    t_ordered = t_APs[ordered_t_idx]                #sort t positions accordingly
-    x_idx_ordered = x_idx_APs[ordered_t_idx]        #sort x positions idx accordingly
-    t_idx_ordered = t_idx_APs[ordered_t_idx]        #sort t positions idx accordingly
+    ordered_t_idx = np.argsort(t_APs)  # sort time indexes
 
-    x_0 = x_ordered[0]                      #get x-position of the first AP in time
+    x_ordered = x_APs[ordered_t_idx]  # sort x positions accordingly
+    t_ordered = t_APs[ordered_t_idx]  # sort t positions accordingly
+    x_idx_ordered = x_idx_APs[ordered_t_idx]  # sort x positions idx accordingly
+    t_idx_ordered = t_idx_APs[ordered_t_idx]  # sort t positions idx accordingly
+
+    x_0 = x_ordered[0]  # get x-position of the first AP in time
     idx_unique = np.sort(np.unique(x_ordered, return_index=True, axis=0)[1])
-    t_min = t_refract 
+    t_min = t_refract
     x_ordered_unique = x_ordered[idx_unique]
     x_ordered_unique.sort()
-    x_min = np.min(np.abs(np.diff(x_ordered_unique)))*5    
-
-    
+    x_min = np.min(np.abs(np.diff(x_ordered_unique))) * 5
 
-    msk_unique = np.arange(len(t_ordered)-1)
+    msk_unique = np.arange(len(t_ordered) - 1)
     msk_unique = [i for i in msk_unique if i not in idx_unique]
-    
-    #get upward APs
+
+    # get upward APs
     idx_up = []
-    idx_up.append(0)                           #add the first one
-    mask = np.full(x_ordered.shape, False)  
-    mask[msk_unique] = True                   
-    mask[np.where(x_ordered<x_0)[0] ] = True   #mask downward APs
-        
-    mask[0] = True                             #mask first AP
-    x_ordered_cpy = x_ordered.copy()           #copy data
-    x_ordered_cpy[mask]=np.nan                 #add nan where mask is true
+    idx_up.append(0)  # add the first one
+    mask = np.full(x_ordered.shape, False)
+    mask[msk_unique] = True
+    mask[np.where(x_ordered < x_0)[0]] = True  # mask downward APs
+
+    mask[0] = True  # mask first AP
+    x_ordered_cpy = x_ordered.copy()  # copy data
+    x_ordered_cpy[mask] = np.nan  # add nan where mask is true
     keep_going = True
-    
-    while (keep_going):
-        if ((np.isnan(x_ordered_cpy).sum())==len(x_ordered_cpy)):   #check if array is full of nan
-           keep_going = False
-        else: 
-            idx = np.nanargmin((x_ordered_cpy - x_0))               #get closest value
-            x_ordered_cpy[idx]=np.nan                               #mask it   
-            
-            if (t_ordered[idx]-t_ordered[idx_up[-1]]>=0):                       #if time val is greater than previous then we reached of end of the AP
-                if (t_ordered[idx]-t_ordered[idx_up[-1]]<t_min):                #if time than the AP refractory period then it doesn't belong to the AP
-                    if (np.abs(x_ordered[idx]-x_ordered[idx_up[-1]])<x_min):    #if it "jumps" to far then it doesn't belong to the AP
-                        idx_up.append(idx)                                
-    
-    #get downward APs
+
+    while keep_going:
+        if (np.isnan(x_ordered_cpy).sum()) == len(
+            x_ordered_cpy
+        ):  # check if array is full of nan
+            keep_going = False
+        else:
+            idx = np.nanargmin((x_ordered_cpy - x_0))  # get closest value
+            x_ordered_cpy[idx] = np.nan  # mask it
+
+            if (
+                t_ordered[idx] - t_ordered[idx_up[-1]] >= 0
+            ):  # if time val is greater than previous then we reached of end of the AP
+                if (
+                    t_ordered[idx] - t_ordered[idx_up[-1]] < t_min
+                ):  # if time than the AP refractory period then it doesn't belong to the AP
+                    if (
+                        np.abs(x_ordered[idx] - x_ordered[idx_up[-1]]) < x_min
+                    ):  # if it "jumps" to far then it doesn't belong to the AP
+                        idx_up.append(idx)
+
+    # get downward APs
     mask = np.full(x_ordered.shape, False)
-    idx_neg = np.where(x_ordered>x_0)[0] 
+    idx_neg = np.where(x_ordered > x_0)[0]
     mask[idx_neg] = True
     mask[0] = True
-    mask[msk_unique] = True 
+    mask[msk_unique] = True
     x_ordered_cpy = x_ordered.copy()
-    x_ordered_cpy[mask]=np.nan
+    x_ordered_cpy[mask] = np.nan
     idx_down = []
     idx_down.append(0)
     keep_going = True
-    while (keep_going):
-        if ((np.isnan(x_ordered_cpy).sum())==len(x_ordered_cpy)):
-           keep_going = False
-        else: 
+    while keep_going:
+        if (np.isnan(x_ordered_cpy).sum()) == len(x_ordered_cpy):
+            keep_going = False
+        else:
             idx = np.nanargmin(-(x_ordered_cpy - x_0))
-            x_ordered_cpy[idx]=np.nan
-            if ((t_ordered[idx]-t_ordered[idx_down[-1]])>=0):
-                if (t_ordered[idx]-t_ordered[idx_down[-1]])<=t_min:         
-                    if (np.abs(x_ordered[idx]-x_ordered[idx_down[-1]])<x_min): 
-                        idx_down.append(idx)                              
-    
-    idx_APs = idx_up+idx_down
+            x_ordered_cpy[idx] = np.nan
+            if (t_ordered[idx] - t_ordered[idx_down[-1]]) >= 0:
+                if (t_ordered[idx] - t_ordered[idx_down[-1]]) <= t_min:
+                    if np.abs(x_ordered[idx] - x_ordered[idx_down[-1]]) < x_min:
+                        idx_down.append(idx)
+
+    idx_APs = idx_up + idx_down
     AP_indexes = np.int32(idx_APs)
     AP_indexes = np.unique(idx_APs)
 
-    return(x_ordered[AP_indexes],x_idx_ordered[AP_indexes],t_ordered[AP_indexes],t_idx_ordered[AP_indexes],ordered_t_idx[AP_indexes])
+    return (
+        x_ordered[AP_indexes],
+        x_idx_ordered[AP_indexes],
+        t_ordered[AP_indexes],
+        t_idx_ordered[AP_indexes],
+        ordered_t_idx[AP_indexes],
+    )
 
-class axon_results(sim_results):
-    """
 
-    """
+class axon_results(sim_results):
+    """"""
 
     def __init__(self, context=None):
         super().__init__(context)
 
+    def generate_axon(self):
+        """
+        generate from the results new version of the simulated axon. Axon generated has the same parameters but is not simulated yet.
+
+        Note
+        ----
+        This function is not defined in ``axon_results`` but in ``unmyelinated_results`` and ``myelinated_results``.
+        """
+        pass
 
-    def is_recruited(self,vm_key:str="V_mem") -> bool:
+    def is_recruited(self, vm_key: str = "V_mem", t_start: float = None) -> bool:
         """
         Return True if an AP is detected, else False.
 
@@ -298,19 +319,28 @@ def is_recruited(self,vm_key:str="V_mem") -> bool:
         is_recruited                : bool
             Return True if an AP is detected, else False.
         """
-        
         if not "recruited" in self:
-            self["recruited"] = self.count_APs(vm_key) != 0
+            n_aps = self.count_APs(vm_key) != 0
+            if n_aps :
+                if t_start is None: 
+                    self["recruited"] = n_aps
+                else:
+                    _,t_starts = self.get_start_APs(vm_key= vm_key)
+                    self["recruited"] = len(t_starts>=t_start) > 0 
+            else:
+                self["recruited"] = n_aps
         return self["recruited"]
-        
-    def is_blocked(self, AP_start:float, freq:float=None, t_refractory:float = 1) -> bool|None:
+
+    def is_blocked(
+        self, AP_start: float, freq: float = None, t_refractory: float = 1
+    ) -> bool | None:
         """
-        check if the axon is blocked or not. 
-        
+        check if the axon is blocked or not.
+
         Warning
         -------
-        A test pulse must be added to generate an AP propagating through the axon. This test AP is used to 
-        validate or not the neural conduction of the axon. 
+        A test pulse must be added to generate an AP propagating through the axon. This test AP is used to
+        validate or not the neural conduction of the axon.
 
         Parameters
         ----------
@@ -328,58 +358,84 @@ def is_blocked(self, AP_start:float, freq:float=None, t_refractory:float = 1) ->
         """
         if not "blocked" in self:
             vm_key = "V_mem"
-            if (freq is not None):
-                self.filter_freq("V_mem",freq , Q= 2)
+            if freq is not None:
+                self.filter_freq("V_mem", freq, Q=2)
                 vm_key += "_filtered"
-            self.rasterize(vm_key = vm_key)
-            _,t_starts = self.get_start_APs(vm_key)
-            n_APs = len(t_starts[t_starts>=AP_start])
-            if n_APs >0:
-                test_AP_idx = nearest_greater_idx(t_starts,AP_start)        #get idx of test AP in the APs list
-                x_APs,_,t_APs,_ = self.split_APs(vm_key)
+            self.rasterize(vm_key=vm_key,clear_artifacts = False)   #artifacts clearing produces strange results :(
+            _, t_starts = self.get_start_APs(vm_key)
+            n_APs = len(t_starts[t_starts >= AP_start])
+
+            t_AP_start = None
+            if n_APs > 0:
+                test_AP_idx = nearest_greater_idx(
+                    t_starts, AP_start
+                )  # get idx of test AP in the APs list
+                x_APs, _, t_APs, _ = self.split_APs(vm_key)
                 x_AP_test = x_APs[test_AP_idx]
                 t_AP_test = t_APs[test_AP_idx]
-                _,t_AP_start = self.get_start_AP(x_AP_test,t_AP_test)
-
-            delta = 0.3
-            if self.myelinated:
-                delta = 0.1
-            if (n_APs == 0 or (t_AP_start >= AP_start + delta)):       #warning: AP start detection is tight (expected after 0.1ms of the test pulse; this might cause issue when triggered by extracellular stimulation)
-                rise_warning(f"is_blocked in Axon {self.ID}: No AP detected after the test pulse. Make sure the stimulus is strong enough, attached to the axon or not colliding with onset response.")
-                return(None)
-            if (n_APs > 2):
-                rise_warning(f"is_blocked in Axon {self.ID}: More than two APs are detected after the test pulse, likely due to onset response. This can cause erroneous block state estimation. Consider increasing axon's spatial discretization.")
-
-            if (self.has_AP_reached_end(x_AP_test,t_AP_test)):  #test AP has reached the end --> is not blocked
+                _, t_AP_start = self.get_start_AP(x_AP_test, t_AP_test)
+
+            delta = 1
+            
+            if n_APs == 0 or (
+                t_AP_start is not None and t_AP_start>= AP_start + delta
+            ):  
+                rise_warning(
+                    f"is_blocked in Axon {self.ID}: No AP detected after the test pulse. Make sure the stimulus is strong enough, attached to the axon or not colliding with onset response. \n ... Fiber considered as blocked."
+                )
+                self["blocked"] = True
+                return self["blocked"]
+            if n_APs > 2:
+                rise_warning(
+                    f"is_blocked in Axon {self.ID}: More than two APs are detected after the test pulse, likely due to onset response. This can cause erroneous block state estimation. \n ... Consider increasing axon's spatial discretization."
+                )
+
+            if self.has_AP_reached_end(
+                x_AP_test, t_AP_test
+            ):  # test AP has reached the end --> is not blocked
                 self["blocked"] = False
                 return self["blocked"]
             else:
-                if not self.is_AP_in_timeframe(x_AP_test,t_AP_test):    #
-                    rise_warning(f"is_blocked in Axon {self.ID}: Test AP didn't not reach axon ends within the simulation timeframe. Consider increasing simulation time or start the test stimulus earlier. ")
-                    return(None)
-                _,_,coll_list = self.get_collision_pts(vm_key)
+                if not self.is_AP_in_timeframe(x_AP_test, t_AP_test):  #
+                    rise_warning(
+                        f"is_blocked in Axon {self.ID}: Test AP didn't not reach axon ends within the simulation timeframe. Consider increasing simulation time or start the test stimulus earlier. "
+                    )
+                    return None
+                _, _, coll_list = self.get_collision_pts(vm_key)
                 if coll_list[test_AP_idx]:
-                    rise_warning(f"is_blocked in Axon {self.ID}: Test AP is colliding with an other AP, probably onset response. Consider increasing the duration between start of block stimulus and test stimulus.")
-                    return(None)
-                
-                t_AP_test_max = np.max(t_AP_test) #test AP last time position:
-                
-                if len(t_starts[t_starts<AP_start]):
-                    if np.min(np.abs(t_starts[t_starts<AP_start]-t_AP_test_max)) < t_refractory: #check if test AP is during refractory period
-                        rise_warning(f"is_blocked in Axon{self.ID}: Test AP occures during axon's refractory period, probably due to onset response. Consider increasing the duration between start of block stimulus and test stimulus.")      
-                        return(None)
-
-                if len(t_starts[t_starts>t_AP_start]): #AP jump
-                    if np.min(np.abs(t_starts[t_starts>AP_start]-t_AP_test_max)) < t_refractory: 
-                        #todo: make sure that the jumping AP is reaching the over side of the axon
+                    rise_warning(
+                        f"is_blocked in Axon {self.ID}: Test AP is colliding with an other AP, probably onset response. Consider increasing the duration between start of block stimulus and test stimulus."
+                    )
+                    return None
+
+                t_AP_test_max = np.max(t_AP_test)  # test AP last time position:
+
+                if len(t_starts[t_starts < AP_start]):
+                    if (
+                        np.min(np.abs(t_starts[t_starts < AP_start] - t_AP_test_max))
+                        < t_refractory
+                    ):  # check if test AP is during refractory period
+                        rise_warning(
+                            f"is_blocked in Axon{self.ID}: Test AP occures during axon's refractory period, probably due to onset response. Consider increasing the duration between start of block stimulus and test stimulus."
+                        )
+                        return None
+
+                if len(t_starts[t_starts > t_AP_start]):  # AP jump
+                    if (
+                        np.min(np.abs(t_starts[t_starts > AP_start] - t_AP_test_max))
+                        < t_refractory
+                    ):
+                        # todo: make sure that the jumping AP is reaching the over side of the axon
                         self["blocked"] = False
                         return self["blocked"]
                 self["blocked"] = True
                 return self["blocked"]
         return self["blocked"]
 
-    def split_APs(self,vm_key:str="V_mem") -> list[np.array] | list[np.array] | list[np.array] | list[np.array] :
-        """        
+    def split_APs(
+        self, vm_key: str = "V_mem"
+    ) -> list[np.array] | list[np.array] | list[np.array] | list[np.array]:
+        """
         Detects individual Action potential in vm_key and split them in lists
 
         Parameters
@@ -389,7 +445,7 @@ def split_APs(self,vm_key:str="V_mem") -> list[np.array] | list[np.array] | list
 
         Returns
         -------
-        list[np.array] 
+        list[np.array]
             list of the x_pos of each AP
         list[np.array]
             list of the x index of each AP
@@ -398,8 +454,8 @@ def split_APs(self,vm_key:str="V_mem") -> list[np.array] | list[np.array] | list
         list[np.array]
             list of the time index of each AP
         """
-        #if not vm_key + "_raster_x_position" in self:
-        self.rasterize(vm_key=vm_key,clear_artifacts=False)
+        # if not vm_key + "_raster_x_position" in self:
+        self.rasterize(vm_key=vm_key, clear_artifacts=False)
         x_APs = []
         x_idx_APs = []
         t_APs = []
@@ -410,12 +466,21 @@ def split_APs(self,vm_key:str="V_mem") -> list[np.array] | list[np.array] | list
         t_idx_raster = self[vm_key + "_raster_time_index"].copy()
 
         min_size = self._get_min_AP_length()
-        
-        if len(x_raster)>min_size:
-            while len(x_raster)>min_size:   
-                x_AP,x_idx_AP,t_AP,t_idx_AP,AP_idx = get_first_AP(x_raster,x_idx_raster,t_raster,t_idx_raster) 
-                AP_len = np.max([self.get_AP_upward_len(x_AP,t_AP),self.get_AP_downward_len(x_AP,t_AP)])
-                if (AP_len>=min_size):   
+        #plt.figure()
+        if len(x_raster) > min_size:
+            while len(x_raster) > min_size:
+                x_AP, x_idx_AP, t_AP, t_idx_AP, AP_idx = get_first_AP(
+                    x_raster, x_idx_raster, t_raster, t_idx_raster
+                )
+                AP_len = np.max(
+                    [
+                        self.get_AP_upward_len(x_AP, t_AP),
+                        self.get_AP_downward_len(x_AP, t_AP),
+                    ]
+                )
+                #print(f"upward: {self.get_AP_upward_len(x_AP, t_AP)} - downward: {self.get_AP_downward_len(x_AP, t_AP)}")
+                #plt.scatter(t_AP,x_AP)
+                if AP_len >= min_size:
                     x_APs.append(x_AP)
                     t_APs.append(t_AP)
                     x_idx_APs.append(x_idx_AP)
@@ -424,10 +489,11 @@ def split_APs(self,vm_key:str="V_mem") -> list[np.array] | list[np.array] | list
                 t_raster = np.delete(t_raster, AP_idx)
                 x_idx_raster = np.delete(x_idx_raster, AP_idx)
                 t_idx_raster = np.delete(t_idx_raster, AP_idx)
-  
-        return(x_APs,x_idx_APs,t_APs,t_idx_APs)
+        #plt.show()
+        #exit()
+        return (x_APs, x_idx_APs, t_APs, t_idx_APs)
 
-    def count_APs(self,vm_key:str="V_mem") -> int:     #**kwargs
+    def count_APs(self, vm_key: str = "V_mem") -> int:  # **kwargs
         """
         Count number of APs detected in vm_key
 
@@ -441,11 +507,11 @@ def count_APs(self,vm_key:str="V_mem") -> int:     #**kwargs
         int
             number of APs detected
         """
-        x,_,_,_ = self.split_APs(vm_key)
-        return(len(x))
-    
-    def _get_min_AP_length(self, min_size: float = .1) -> int:
-        """ 
+        x, _, _, _ = self.split_APs(vm_key)
+        return len(x)
+
+    def _get_min_AP_length(self, min_size: float = 0.1) -> int:
+        """
         Returns the minimum propation length of an AP, set to 10% of the axon length by default
 
         Parameters
@@ -462,9 +528,9 @@ def _get_min_AP_length(self, min_size: float = .1) -> int:
             n_x = len(self.node_index)
         else:
             n_x = len(self.x_rec)
-        return(int(n_x*min_size))
+        return int(n_x * min_size)
 
-    def get_start_AP(self,x_AP:np.array, t_AP:np.array) -> float|float:
+    def get_start_AP(self, x_AP: np.array, t_AP: np.array) -> float | float:
         """
         Returns the x,t start values of the AP
 
@@ -483,9 +549,9 @@ def get_start_AP(self,x_AP:np.array, t_AP:np.array) -> float|float:
             t start value of the AP
         """
         start_idx = t_AP.argmin()
-        return(x_AP[start_idx],t_AP[start_idx])
+        return (x_AP[start_idx], t_AP[start_idx])
 
-    def get_start_APs(self,vm_key:str="V_mem") -> NDArray|NDArray:
+    def get_start_APs(self, vm_key: str = "V_mem") -> NDArray | NDArray:
         """
         Return list of (x,t) start positions of each detected APs
 
@@ -503,18 +569,16 @@ def get_start_APs(self,vm_key:str="V_mem") -> NDArray|NDArray:
         NDArray
             Array of the start t-position of each APs
         """
-        x_APs,_,t_APs,_ = self.split_APs(vm_key)
+        x_APs, _, t_APs, _ = self.split_APs(vm_key)
         x_AP_start = []
         t_AP_start = []
-        for x_AP,t_AP in zip(x_APs,t_APs):
-            x_AP_s,t_AP_s = self.get_start_AP(x_AP,t_AP)
+        for x_AP, t_AP in zip(x_APs, t_APs):
+            x_AP_s, t_AP_s = self.get_start_AP(x_AP, t_AP)
             x_AP_start.append(x_AP_s)
             t_AP_start.append(t_AP_s)
-        return(np.array(x_AP_start),np.array(t_AP_start))
-
-        
+        return (np.array(x_AP_start), np.array(t_AP_start))
 
-    def get_xmax_AP(self,x_AP:np.array ,t_AP:np.array) -> float|float:
+    def get_xmax_AP(self, x_AP: np.array, t_AP: np.array) -> float | float:
         """
         Returns the x,t values the maximum AP x-position
 
@@ -533,9 +597,9 @@ def get_xmax_AP(self,x_AP:np.array ,t_AP:np.array) -> float|float:
             t value of the maximum AP x-position
         """
         max_idx = x_AP.argmax()
-        return(x_AP[max_idx],t_AP[max_idx])
+        return (x_AP[max_idx], t_AP[max_idx])
 
-    def get_xmin_AP(self,x_AP:np.array ,t_AP:np.array) -> float|float:
+    def get_xmin_AP(self, x_AP: np.array, t_AP: np.array) -> float | float:
         """
         Returns the x,t values the minimum AP x-position
 
@@ -554,9 +618,9 @@ def get_xmin_AP(self,x_AP:np.array ,t_AP:np.array) -> float|float:
             t value of the minimum AP x-position
         """
         min_idx = x_AP.argmin()
-        return(x_AP[min_idx],t_AP[min_idx])
-    
-    def get_AP_upward_len(self,x_AP:np.array ,t_AP:np.array) -> int:
+        return (x_AP[min_idx], t_AP[min_idx])
+
+    def get_AP_upward_len(self, x_AP: np.array, t_AP: np.array) -> int:
         """
         Returns the length (number of x pts) of the AP in the upward direction
 
@@ -572,12 +636,12 @@ def get_AP_upward_len(self,x_AP:np.array ,t_AP:np.array) -> int:
         int
             number of AP x-pos points in the upward direction
         """
-        x_start,_= self.get_start_AP(x_AP,t_AP)
-        x_max,_= self.get_xmax_AP(x_AP,t_AP)
-        len_upward = x_AP[((x_AP>= x_start) & (x_AP<= x_max))]
-        return(len(len_upward))
-        
-    def get_AP_downward_len(self,x_AP:np.array ,t_AP:np.array) -> int:
+        x_start, _ = self.get_start_AP(x_AP, t_AP)
+        x_max, _ = self.get_xmax_AP(x_AP, t_AP)
+        len_upward = x_AP[((x_AP >= x_start) & (x_AP <= x_max))]
+        return len(len_upward)
+
+    def get_AP_downward_len(self, x_AP: np.array, t_AP: np.array) -> int:
         """
         Returns the length (number of x pts) of the AP in the downward direction
 
@@ -593,12 +657,12 @@ def get_AP_downward_len(self,x_AP:np.array ,t_AP:np.array) -> int:
         int
             number of AP x-pos points in the downward direction
         """
-        x_start,_= self.get_start_AP(x_AP,t_AP)
-        x_max,_= self.get_xmax_AP(x_AP,t_AP)
-        len_downward = x_AP[((x_AP<= x_start) & (x_AP>= x_max))]
-        return(len(len_downward)) 
+        x_start, _ = self.get_start_AP(x_AP, t_AP)
+        x_min, _ = self.get_xmin_AP(x_AP, t_AP)
+        len_downward = x_AP[((x_AP <= x_start) & (x_AP >= x_min))]
+        return len(len_downward)
 
-    def has_AP_reached_end(self,x_AP:np.array ,t_AP:np.array) -> bool:
+    def has_AP_reached_end(self, x_AP: np.array, t_AP: np.array) -> bool:
         """
         Return true if the AP has reached the end of the axon in both direction, else false
 
@@ -617,11 +681,11 @@ def has_AP_reached_end(self,x_AP:np.array ,t_AP:np.array) -> bool:
         x = self.get_axon_xrec()
         x_max = np.max(x)
         x_min = np.min(x)
-        x_max_AP,_ = self.get_xmax_AP(x_AP,t_AP)
-        x_min_AP,_ = self.get_xmin_AP(x_AP,t_AP)
-        return(x_max==x_max_AP and x_min_AP==x_min)
-    
-    def APs_reached_end(self,vm_key:str="V_mem") -> bool:
+        x_max_AP, _ = self.get_xmax_AP(x_AP, t_AP)
+        x_min_AP, _ = self.get_xmin_AP(x_AP, t_AP)
+        return x_max == x_max_AP and x_min_AP == x_min
+
+    def APs_reached_end(self, vm_key: str = "V_mem") -> bool:
         """
         Return true if ALL APs have reached the both ends of the axon
 
@@ -636,14 +700,14 @@ def APs_reached_end(self,vm_key:str="V_mem") -> bool:
             True if ALL APs have reached the both ends of the axon, else False
         """
 
-        x_APs,_,t_APs,_ = self.split_APs(vm_key=vm_key)
-        if (len(x_APs)):
-            for x_AP,t_AP in zip(x_APs,t_APs):
-                if (not self.has_AP_reached_end(x_AP,t_AP)):
+        x_APs, _, t_APs, _ = self.split_APs(vm_key=vm_key)
+        if len(x_APs):
+            for x_AP, t_AP in zip(x_APs, t_APs):
+                if not self.has_AP_reached_end(x_AP, t_AP):
                     return False
         return True
-    
-    def is_AP_in_timeframe(self,x_AP:np.array ,t_AP:np.array) -> bool:
+
+    def is_AP_in_timeframe(self, x_AP: np.array, t_AP: np.array) -> bool:
         """
         Return true if AP has reached it's last position (in both direction) within the simulation timeframe, else False
 
@@ -659,29 +723,29 @@ def is_AP_in_timeframe(self,x_AP:np.array ,t_AP:np.array) -> bool:
         bool
             true if AP has reached its last position (in both direction) within the simulation timeframe, else False
         """
-        if (self.has_AP_reached_end(x_AP,t_AP)):
+        if self.has_AP_reached_end(x_AP, t_AP):
             return True
         else:
-            up_len = self.get_AP_upward_len(x_AP,t_AP)
-            down_len = self.get_AP_downward_len(x_AP,t_AP)
-            _,t_start = self.get_start_AP(x_AP,t_AP)
-            if (up_len>down_len):
-                _,t_stop = self.get_xmax_AP(x_AP,t_AP)
-                dt_AP = (t_stop - t_start)/up_len
+            up_len = self.get_AP_upward_len(x_AP, t_AP)
+            down_len = self.get_AP_downward_len(x_AP, t_AP)
+            _, t_start = self.get_start_AP(x_AP, t_AP)
+            if up_len > down_len:
+                _, t_stop = self.get_xmax_AP(x_AP, t_AP)
+                dt_AP = (t_stop - t_start) / up_len
             else:
-                _,t_stop = self.get_xmin_AP(x_AP,t_AP)
-                dt_AP = (t_stop - t_start)/down_len 
-            
-            if (dt_AP<0.5):
+                _, t_stop = self.get_xmin_AP(x_AP, t_AP)
+                dt_AP = (t_stop - t_start) / down_len
+
+            if dt_AP < 0.5:
                 dt_AP = 0.5
-            _,t_xmax_AP = self.get_xmax_AP(x_AP,t_AP)
-            _,t_xmin_AP = self.get_xmin_AP(x_AP,t_AP)
+            _, t_xmax_AP = self.get_xmax_AP(x_AP, t_AP)
+            _, t_xmin_AP = self.get_xmin_AP(x_AP, t_AP)
             tmax = np.max(self.t)
-            if ((t_xmax_AP+dt_AP > tmax) or (t_xmin_AP+dt_AP > 10*tmax)):
-                return(False)
-            return(True)
+            if (t_xmax_AP + dt_AP > tmax) or (t_xmin_AP + dt_AP > 10 * tmax):
+                return False
+            return True
 
-    def APs_in_timeframe(self,vm_key:str="V_mem") -> bool:
+    def APs_in_timeframe(self, vm_key: str = "V_mem") -> bool:
         """
         Return true if ALL APs have reached their last position (in both direction) within the simulation timeframe, else False
 
@@ -695,17 +759,17 @@ def APs_in_timeframe(self,vm_key:str="V_mem") -> bool:
         bool
             True if ALL APs have reached their last position (in both direction) within the simulation timeframe, else False
         """
-        x_APs,_,t_APs,_ = self.split_APs(vm_key=vm_key)
-        if (len(x_APs)):
-            for x_AP,t_AP in zip(x_APs,t_APs):
-                if (not self.is_AP_in_timeframe(x_AP,t_AP)):
+        x_APs, _, t_APs, _ = self.split_APs(vm_key=vm_key)
+        if len(x_APs):
+            for x_AP, t_AP in zip(x_APs, t_APs):
+                if not self.is_AP_in_timeframe(x_AP, t_AP):
                     return False
         return True
-        
-    def get_collision_pts(self,vm_key:str="V_mem") -> list[float]|list[float]:
+
+    def get_collision_pts(self, vm_key: str = "V_mem") -> list[float] | list[float]:
         """
         Returns three lists: - two containing the x,t coordinates of the interAPs colliding coordinates
-                             - one boolean list where true means the AP is colliding, else false 
+                             - one boolean list where true means the AP is colliding, else false
 
         Parameters
         ----------
@@ -721,36 +785,40 @@ def get_collision_pts(self,vm_key:str="V_mem") -> list[float]|list[float]:
         list[bool]
             list of colliding APs: true when colliding else false
         """
-        x_APs,_,t_APs,_ = self.split_APs(vm_key=vm_key)
+        x_APs, _, t_APs, _ = self.split_APs(vm_key=vm_key)
         x_APs_coll = []
         t_APs_coll = []
         idx_coll = []
-        colliding_list =  [False for i in range(len(x_APs))]
+        colliding_list = [False for i in range(len(x_APs))]
         idx_APs = np.arange(len(x_APs))
-        
-        for x_AP,t_AP,idx_AP in zip(x_APs,t_APs,idx_APs):
-            if (not self.has_AP_reached_end(x_AP,t_AP)):
+
+        for x_AP, t_AP, idx_AP in zip(x_APs, t_APs, idx_APs):
+            if not self.has_AP_reached_end(x_AP, t_AP):
                 x_APs_coll.append(x_AP)
                 t_APs_coll.append(t_AP)
                 idx_coll.append(idx_AP)
-        if len(x_APs_coll)<=1: #need at least 2 APs to get a collision 
-            return([],[],colliding_list)
+        if len(x_APs_coll) <= 1:  # need at least 2 APs to get a collision
+            return ([], [], colliding_list)
         ids = np.arange(len(x_APs_coll))
-        comb_list = list(combinations(ids,2))
+        comb_list = list(combinations(ids, 2))
         x_coll_l = []
         t_coll_l = []
         for idx_comb in comb_list:
-            x_inter, t_inter = self.get_interAPs_collision(x_APs_coll[idx_comb[0]],t_APs_coll[idx_comb[0]],
-                                        x_APs_coll[idx_comb[1]],t_APs_coll[idx_comb[1]])
-            if (x_inter and t_inter)>0:
+            x_inter, t_inter = self.get_interAPs_collision(
+                x_APs_coll[idx_comb[0]],
+                t_APs_coll[idx_comb[0]],
+                x_APs_coll[idx_comb[1]],
+                t_APs_coll[idx_comb[1]],
+            )
+            if (x_inter and t_inter) > 0:
                 x_coll_l.append(x_inter)
                 t_coll_l.append(t_inter)
                 colliding_list[idx_coll[idx_comb[1]]] = True
                 colliding_list[idx_coll[idx_comb[0]]] = True
 
-        return(x_coll_l,t_coll_l,colliding_list)
-    
-    def detect_AP_collisions(self,vm_key:str="V_mem") -> bool:
+        return (x_coll_l, t_coll_l, colliding_list)
+
+    def detect_AP_collisions(self, vm_key: str = "V_mem") -> bool:
         """
         Return True is at least one collision between two APs is detected, else False
 
@@ -764,12 +832,14 @@ def detect_AP_collisions(self,vm_key:str="V_mem") -> bool:
         bool
             True if an interAP collision is detected, else False
         """
-        _,t_coll,_ = self.get_collision_pts(vm_key)
+        _, t_coll, _ = self.get_collision_pts(vm_key)
         if len(t_coll):
-            return(True)
-        return(False)
-    
-    def get_interAPs_collision(self, x_AP1:NDArray, t_AP1:NDArray, x_AP2:NDArray, t_AP2:NDArray) -> float|float:
+            return True
+        return False
+
+    def get_interAPs_collision(
+        self, x_AP1: NDArray, t_AP1: NDArray, x_AP2: NDArray, t_AP2: NDArray
+    ) -> float | float:
         """
         Returns the estimated collision coordinates of two APs. Returns (0,0) if the collision is out of scope.
 
@@ -790,35 +860,45 @@ def get_interAPs_collision(self, x_AP1:NDArray, t_AP1:NDArray, x_AP2:NDArray, t_
         float
             t position of the intersection (collision) point. Is 0 is the position is out of scope
         """
-        poly_up_1,poly_down_1 = self.linfit_AP(x_AP1,t_AP1)
-        poly_up_2,poly_down_2 = self.linfit_AP(x_AP2,t_AP2)
-        x_inter1,t_inter1 = self.get_1dpoly_intersec(poly_up_1,poly_down_2)
-        x_inter2,t_inter2 = self.get_1dpoly_intersec(poly_up_2,poly_down_1)
+        poly_up_1, poly_down_1 = self.linfit_AP(x_AP1, t_AP1)
+        poly_up_2, poly_down_2 = self.linfit_AP(x_AP2, t_AP2)
+        x_inter1, t_inter1 = self.get_1dpoly_intersec(poly_up_1, poly_down_2)
+        x_inter2, t_inter2 = self.get_1dpoly_intersec(poly_up_2, poly_down_1)
 
-        x1_max,t1_max = self.get_xmax_AP(x_AP1,t_AP1)
-        x1_min,t1_min = self.get_xmin_AP(x_AP1,t_AP1)
+        x1_max, t1_max = self.get_xmax_AP(x_AP1, t_AP1)
+        x1_min, t1_min = self.get_xmin_AP(x_AP1, t_AP1)
 
-        x2_max,t2_max = self.get_xmax_AP(x_AP2,t_AP2)
-        x2_min,t2_min = self.get_xmin_AP(x_AP2,t_AP2)
+        x2_max, t2_max = self.get_xmax_AP(x_AP2, t_AP2)
+        x2_min, t2_min = self.get_xmin_AP(x_AP2, t_AP2)
 
-        if self._pts_in_sim_range(x_inter1,t_inter1) and self._pts_in_sim_range(x_inter2,t_inter2):
-            if t_inter2>t_inter1:
-                if self._AP_pt_in_range(x1_max,t1_max,x_inter2,t_inter2) and self._AP_pt_in_range(x2_min,t2_min,x_inter2,t_inter2):
+        if self._pts_in_sim_range(x_inter1, t_inter1) and self._pts_in_sim_range(
+            x_inter2, t_inter2
+        ):
+            if t_inter2 > t_inter1:
+                if self._AP_pt_in_range(
+                    x1_max, t1_max, x_inter2, t_inter2
+                ) and self._AP_pt_in_range(x2_min, t2_min, x_inter2, t_inter2):
                     if t_inter2 > (t1_max and t2_min):
                         return x_inter2, t_inter2
-                if self._AP_pt_in_range(x1_min,t1_min,x_inter2,t_inter2) and self._AP_pt_in_range(x2_max,t2_max,x_inter2,t_inter2):
+                if self._AP_pt_in_range(
+                    x1_min, t1_min, x_inter2, t_inter2
+                ) and self._AP_pt_in_range(x2_max, t2_max, x_inter2, t_inter2):
                     if t_inter2 > (t1_min and t2_max):
                         return x_inter2, t_inter2
             else:
-                if self._AP_pt_in_range(x1_max,t1_max,x_inter1,t_inter1) and self._AP_pt_in_range(x2_min,t2_min,x_inter1,t_inter1):
+                if self._AP_pt_in_range(
+                    x1_max, t1_max, x_inter1, t_inter1
+                ) and self._AP_pt_in_range(x2_min, t2_min, x_inter1, t_inter1):
                     if t_inter1 > (t1_max and t2_min):
                         return x_inter1, t_inter1
-                if self._AP_pt_in_range(x1_min,t1_min,x_inter1,t_inter1) and self._AP_pt_in_range(x2_max,t2_max,x_inter1,t_inter1):
+                if self._AP_pt_in_range(
+                    x1_min, t1_min, x_inter1, t_inter1
+                ) and self._AP_pt_in_range(x2_max, t2_max, x_inter1, t_inter1):
                     if t_inter1 > (t1_min and t2_max):
                         return x_inter1, t_inter1
         return 0, 0
 
-    def _pts_in_sim_range(self, x:float,t:float) -> bool:
+    def _pts_in_sim_range(self, x: float, t: float) -> bool:
         """
         Returns true if the (x,t) point is within the simulation range
 
@@ -836,9 +916,11 @@ def _pts_in_sim_range(self, x:float,t:float) -> bool:
         """
         x_max = np.max(self.get_axon_xrec())
         t_max = np.max(self.t)
-        return((x < x_max) and (x > 0) and (t > 0) and (t < t_max))
+        return (x < x_max) and (x > 0) and (t > 0) and (t < t_max)
 
-    def _AP_pt_in_range(self, x1:float, t1:float, x2:float, t2:float, tol:float = 0.12) -> bool:
+    def _AP_pt_in_range(
+        self, x1: float, t1: float, x2: float, t2: float, tol: float = 0.12
+    ) -> bool:
         """
         Return true is the point (x1,t1) and (x2,t2) are within a range, set by tol
 
@@ -860,10 +942,9 @@ def _AP_pt_in_range(self, x1:float, t1:float, x2:float, t2:float, tol:float = 0.
         bool
             True if the two points are within the range
         """
-        return(np.abs(x1-x2)<=tol*x1 and np.abs(t1-t2)<=tol*t1)
+        return np.abs(x1 - x2) <= tol * x1 and np.abs(t1 - t2) <= tol * t1
 
-
-    def get_1dpoly_intersec(self, poly1:np.poly1d, poly2:np.poly1d) -> float|float:
+    def get_1dpoly_intersec(self, poly1: np.poly1d, poly2: np.poly1d) -> float | float:
         """
         Returns the intersection points of two 1D poly
 
@@ -881,10 +962,10 @@ def get_1dpoly_intersec(self, poly1:np.poly1d, poly2:np.poly1d) -> float|float:
         float
             x intersection point
         """
-        x_inter = (poly2.c[1]-poly1.c[1])/(poly1.c[0]-poly2.c[0])
-        return(poly1(x_inter),x_inter)
+        x_inter = (poly2.c[1] - poly1.c[1]) / (poly1.c[0] - poly2.c[0])
+        return (poly1(x_inter), x_inter)
 
-    def linfit_AP(self, x_AP:NDArray, t_AP:NDArray) -> np.poly1d|np.poly1d:
+    def linfit_AP(self, x_AP: NDArray, t_AP: NDArray) -> np.poly1d | np.poly1d:
         """
         Fit the AP with two 1D polynomial equations: one for the upward propagation, one for the downward propagation
 
@@ -902,12 +983,12 @@ def linfit_AP(self, x_AP:NDArray, t_AP:NDArray) -> np.poly1d|np.poly1d:
         np.poly1d
             AP downward direction 1D poly fit
         """
-        x_max,_ = self.get_xmax_AP(x_AP,t_AP)
-        x_min,_ = self.get_xmin_AP(x_AP,t_AP)
-        x_start,_ = self.get_start_AP(x_AP,t_AP)
+        x_max, _ = self.get_xmax_AP(x_AP, t_AP)
+        x_min, _ = self.get_xmin_AP(x_AP, t_AP)
+        x_start, _ = self.get_start_AP(x_AP, t_AP)
 
-        #fit upward AP
-        upward_idx = np.argwhere((x_AP>= x_start) & (x_AP<= x_max))
+        # fit upward AP
+        upward_idx = np.argwhere((x_AP >= x_start) & (x_AP <= x_max))
         upward_idx = [x[0] for x in upward_idx]
         x_AP_up = x_AP[upward_idx]
         t_AP_up = t_AP[upward_idx]
@@ -916,8 +997,8 @@ def linfit_AP(self, x_AP:NDArray, t_AP:NDArray) -> np.poly1d|np.poly1d:
         x_AP_up = x_AP_up[idx_sorted]
         p_up = np.poly1d(np.polyfit(t_AP_up, x_AP_up, 1))
 
-        #fit downward AP
-        downward_idx = np.argwhere((x_AP<= x_start) & (x_AP>= x_min))
+        # fit downward AP
+        downward_idx = np.argwhere((x_AP <= x_start) & (x_AP >= x_min))
         downward_idx = [x[0] for x in downward_idx]
         x_AP_down = x_AP[downward_idx]
         t_AP_down = t_AP[downward_idx]
@@ -925,7 +1006,7 @@ def linfit_AP(self, x_AP:NDArray, t_AP:NDArray) -> np.poly1d|np.poly1d:
         t_AP_down = t_AP_down[idx_sorted]
         x_AP_down = x_AP_down[idx_sorted]
         p_down = np.poly1d(np.polyfit(t_AP_down, x_AP_down, 1))
-        return(p_up,p_down)
+        return (p_up, p_down)
 
     def get_axon_xrec(self) -> NDArray:
         """
@@ -945,9 +1026,9 @@ def get_axon_xrec(self) -> NDArray:
                 x = self["x_rec"]
         else:
             x = self["x_rec"]
-        return(x)
+        return x
 
-    def get_avg_AP_speed(self,vm_key:str="V_mem") -> float : 
+    def get_avg_AP_speed(self, vm_key: str = "V_mem") -> float:
         """
         Returns the averaged propagtion speed of each APs, in m/s.
 
@@ -963,14 +1044,14 @@ def get_avg_AP_speed(self,vm_key:str="V_mem") -> float :
         """
         ap_speed = self.getAPspeed(vm_key)
         if len(ap_speed):
-            return np.round(np.mean(ap_speed),3)
+            return np.round(np.mean(ap_speed), 3)
         else:
             rise_warning("No AP detected, can't evaluate AP propagation speed.")
-            return(0.0)
+            return 0.0
 
-    def getAPspeed(self,vm_key:str="V_mem") -> list[float]:
+    def getAPspeed(self, vm_key: str = "V_mem") -> list[float]:
         """
-        Return the propagtion speed of each APs, in m/s 
+        Return the propagtion speed of each APs, in m/s
 
         Parameters
         ----------
@@ -980,20 +1061,20 @@ def getAPspeed(self,vm_key:str="V_mem") -> list[float]:
         Returns
         -------
         list[float]
-            list of propagation speed of each APs, in m/s 
-        """  
-        x_APs,_,t_APs,_ = self.split_APs(vm_key=vm_key)
+            list of propagation speed of each APs, in m/s
+        """
+        x_APs, _, t_APs, _ = self.split_APs(vm_key=vm_key)
         APspeed = []
-        if (len(x_APs)):
-            for x_AP,t_AP in zip(x_APs,t_APs):
-                APspeed.append(np.round(self._APspeed(x_AP,t_AP),3))
+        if len(x_APs):
+            for x_AP, t_AP in zip(x_APs, t_APs):
+                APspeed.append(np.round(self._APspeed(x_AP, t_AP), 3))
         if len(APspeed):
-            return(APspeed)
+            return APspeed
         else:
             rise_warning("No AP detected, can't evaluate AP propagation speed.")
-            return([])
-        
-    def _APspeed(self, x_AP:NDArray, t_AP:NDArray) -> float:
+            return []
+
+    def _APspeed(self, x_AP: NDArray, t_AP: NDArray) -> float:
         """
         Evaluate the propagation speed of one AP, in m/s
 
@@ -1009,15 +1090,15 @@ def _APspeed(self, x_AP:NDArray, t_AP:NDArray) -> float:
         float
             propagation of the AP, in m/s
         """
-        x_start,t_start = self.get_start_AP(x_AP,t_AP)
-        #if self.get_AP_upward_len(x_AP,t_AP) > self.get_AP_downward_len(x_AP,t_AP):
-        x_stop,t_stop  = self.get_xmax_AP(x_AP,t_AP)
-        #else:
+        x_start, t_start = self.get_start_AP(x_AP, t_AP)
+        # if self.get_AP_upward_len(x_AP,t_AP) > self.get_AP_downward_len(x_AP,t_AP):
+        x_stop, t_stop = self.get_xmax_AP(x_AP, t_AP)
+        # else:
         #    x_stop,t_stop  = self.get_xmin_AP(x_AP,t_AP)
-        speed = np.abs(x_stop-x_start)/(t_stop-t_start)
-        return(speed*1e-3)
+        speed = np.abs(x_stop - x_start) / (t_stop - t_start)
+        return speed * 1e-3
 
-    def remove_raster_artifacts(self,vm_key:str="V_mem") -> None:     #**kwargs
+    def remove_raster_artifacts(self, vm_key: str = "V_mem") -> None:  # **kwargs
         """
         Remove artifacts (non-APs) rasterized points.
 
@@ -1026,24 +1107,26 @@ def remove_raster_artifacts(self,vm_key:str="V_mem") -> None:     #**kwargs
         vm_key : str, optional
             Rasterized Vmembrane key , by default "V_mem"
         """
-        x_APs,x_idx,t_APs,t_idx = self.split_APs(vm_key)
+        x_APs, x_idx, t_APs, t_idx = self.split_APs(vm_key)
         x_clean = []
         x_idx_clean = []
         t_clean = []
         t_idx_clean = []
 
-        for i,_ in enumerate(x_APs):
-            x_clean+=list(x_APs[i])
-            x_idx_clean+=list(x_idx[i]) 
-            t_clean+=list(t_APs[i]) 
-            t_idx_clean+=list(t_idx[i]) 
-            
+        for i, _ in enumerate(x_APs):
+            x_clean += list(x_APs[i])
+            x_idx_clean += list(x_idx[i])
+            t_clean += list(t_APs[i])
+            t_idx_clean += list(t_idx[i])
+
         self[vm_key + "_raster_position"] = np.array(x_idx_clean)
         self[vm_key + "_raster_x_position"] = np.array(x_clean)
         self[vm_key + "_raster_time_index"] = np.array(t_idx_clean)
         self[vm_key + "_raster_time"] = np.array(t_clean)
 
-    def rasterize(self, vm_key:str="V_mem", clear_artifacts:bool = True,**kwargs) -> None :
+    def rasterize(
+        self, vm_key: str = "V_mem", clear_artifacts: bool = True, **kwargs
+    ) -> None:
         """
         Rasterize a membrane potential (or filtered or any quantity processed from membrane voltage), with AP detection.
         This function adds 4 items to the class, with the key termination '_raster_position', '_raster_x_position', '_raster_time_index', '_raster_time' concatenated to the original key.
@@ -1062,7 +1145,7 @@ def rasterize(self, vm_key:str="V_mem", clear_artifacts:bool = True,**kwargs) ->
         clear_artifacts : bool
             if True, remove artifacts (non-APs) rasterized points. By default True.
 
-        **kwargs: 
+        **kwargs:
             - threshold: (float) threshold for AP detection, in mV. Default value is taken from axon model
             - t_min_AP: (float) minimum AP duration, in ms. Default is 0.1ms
             - t_refractory: (float) inter-AP duration, in ms. Default is 0.5ms
@@ -1070,6 +1153,7 @@ def rasterize(self, vm_key:str="V_mem", clear_artifacts:bool = True,**kwargs) ->
             - t_stop: (float) stop time for rasterize, in ms. Default is simulation time.
         """
 
+        #clear_artifacts = False
         if not vm_key + "_raster_position" in self:
 
             if "threshold" in kwargs:
@@ -1080,17 +1164,17 @@ def rasterize(self, vm_key:str="V_mem", clear_artifacts:bool = True,**kwargs) ->
             if "t_min_AP" in kwargs:
                 t_min_AP = kwargs["t_min_AP"]
             else:
-                t_min_AP=0.1
+                t_min_AP = 0.1
 
             if "t_refractory" in kwargs:
                 t_refractory = kwargs["t_refractory"]
             else:
-                t_refractory=0.5
+                t_refractory = 0.5
 
             t_start = None
             if "t_start" in kwargs:
                 t_start = kwargs["t_start"]
-            
+
             t_stop = None
             if "t_stop" in kwargs:
                 t_start = kwargs["t_stop"]
@@ -1107,14 +1191,24 @@ def rasterize(self, vm_key:str="V_mem", clear_artifacts:bool = True,**kwargs) ->
             else:
                 x = self["x_rec"]
 
-            (self[vm_key + "_raster_position"],self[vm_key + "_raster_x_position"],
-            self[vm_key + "_raster_time_index"],self[vm_key + "_raster_time"]) = rasterize(y_data=vm,x_data=x,
-                                t_data=self.t,threshold=threshold,t_min_AP=t_min_AP,t_refractory=t_refractory,t_start=t_start,
-                                t_stop=t_stop)
-            if (clear_artifacts):
+            (
+                self[vm_key + "_raster_position"],
+                self[vm_key + "_raster_x_position"],
+                self[vm_key + "_raster_time_index"],
+                self[vm_key + "_raster_time"],
+            ) = rasterize(
+                y_data=vm,
+                x_data=x,
+                t_data=self.t,
+                threshold=threshold,
+                t_min_AP=t_min_AP,
+                t_refractory=t_refractory,
+                t_start=t_start,
+                t_stop=t_stop,
+            )
+            if clear_artifacts:
                 self.remove_raster_artifacts(vm_key)
 
-
     def speed(self, position_key=None, t_start=0, t_stop=0, x_start=0, x_stop=0):
         """
         Compute the velocity of a spike from rasterized data in a dictionary. The speed can be either positive or negative depending on the propagation direction.
@@ -1143,8 +1237,8 @@ def speed(self, position_key=None, t_start=0, t_stop=0, x_start=0, x_stop=0):
         """
 
         rise_warning(
-        "DeprecationWarning: ",
-        "speed is obsolete, please use get_avg_AP_speed() instead"
+            "DeprecationWarning: ",
+            "speed is obsolete, please use get_avg_AP_speed() instead",
         )
         # define max timing if not already defined
         if t_stop == 0:
@@ -1177,7 +1271,9 @@ def speed(self, position_key=None, t_start=0, t_stop=0, x_start=0, x_stop=0):
         inf_position_indexes = np.where(
             self[good_key_prefix + "_x_position"][good_indexes_time] <= x_stop
         )
-        good_indexes_position = np.intersect1d(sup_position_indexes, inf_position_indexes)
+        good_indexes_position = np.intersect1d(
+            sup_position_indexes, inf_position_indexes
+        )
         good_indexes = np.intersect1d(good_indexes_position, good_indexes_time)
         good_spike_times = self[good_key_prefix + "_time"][good_indexes]
         good_spike_positions = self[good_key_prefix + "_x_position"][good_indexes]
@@ -1190,7 +1286,6 @@ def speed(self, position_key=None, t_start=0, t_stop=0, x_start=0, x_stop=0):
         )
         return speed
 
-
     def block(self, position_key=None, t_start=0, t_stop=0):
         """
         check if an axon is blocked or not. The simulation has to include the test spike. This function will look for the test spike initiation and check the propagation
@@ -1286,7 +1381,6 @@ def block(self, position_key=None, t_start=0, t_stop=0):
         else:
             rise_error("intra_stim_positions is not in dictionnary")
 
-
     def check_test_AP(self):
         """
         Check if a test AP is correctely triggered during an axon simulation and if so return the\
@@ -1303,10 +1397,7 @@ def check_test_AP(self):
             time in ms of the first test AP during the simulation. None if no test AP found
         """
 
-        rise_warning(
-        "DeprecationWarning: ",
-        "check_test_AP is obsolete"
-        )
+        rise_warning("DeprecationWarning: ", "check_test_AP is obsolete")
         if type(self) == str:
             self = self.load_simulation_from_json()
         if "intra_stim_starts" not in self:
@@ -1330,7 +1421,6 @@ def check_test_AP(self):
                 test_AP = None
             return test_AP
 
-
     def detect_start_extrastim(self, threshold=None):
         """
         Returns the starting time of extracellular stimulation from axon simulation results
@@ -1349,10 +1439,7 @@ def detect_start_extrastim(self, threshold=None):
             list of stimulation starting time in ms, float if only one stimulation and None if no stimulation
         """
 
-        rise_warning(
-        "DeprecationWarning: ",
-        "detect_start_extrastim is obsolete"
-        )
+        rise_warning("DeprecationWarning: ", "detect_start_extrastim is obsolete")
         t_start = []
         if "extracellular_stimuli" in self:
             for i in range(len(self["extracellular_stimuli"])):
@@ -1370,7 +1457,6 @@ def detect_start_extrastim(self, threshold=None):
             t_start = t_start[0]
         return t_start
 
-
     def extra_stim_properties(self):
         """
         Return elect caracteristics (blocked, Onset response, ...)
@@ -1389,17 +1475,15 @@ def extra_stim_properties(self):
             electrode["y"] = self["extracellular_electrode_y"]
             electrode["z"] = self["extracellular_electrode_z"]
             electrode["start"] = self.detect_start_extrastim(self)
-            electrode["max amplitude"] = [
-                max(s) for s in self["extracellular_stimuli"]
-            ]
+            electrode["max amplitude"] = [max(s) for s in self["extracellular_stimuli"]]
 
         return electrode
 
-
-    def block_summary(self, AP_start:float, freq:float=None, t_refractory:float = 1) -> dict:
-        
+    def block_summary(
+        self, AP_start: float, freq: float = None, t_refractory: float = 1
+    ) -> dict:
         """
-        Return axon block characteristics: blocked, onset response, number of APs) 
+        Return axon block characteristics: blocked, onset response, number of APs)
 
         Parameters
         ----------
@@ -1413,35 +1497,43 @@ def block_summary(self, AP_start:float, freq:float=None, t_refractory:float = 1)
         Returns
         -------
         axon_state       : dict
-            tuple containing the block characteristics: is_blocked (bool), has_onset (bool), n_onset (int) 
+            tuple containing the block characteristics: is_blocked (bool), has_onset (bool), n_onset (int)
         """
 
-        if {'is_blocked','has_onset','n_onset'} not in self:
+        if {"is_blocked", "has_onset", "n_onset"} not in self:
             required_keys = {"V_mem"}
             if required_keys in self:
                 vm_key = "V_mem"
-                if (freq is not None):
-                    self.filter_freq("V_mem",freq , Q= 2)
+                if freq is not None:
+                    self.filter_freq("V_mem", freq, Q=2)
                     vm_key += "_filtered"
 
-                blocked = self.is_blocked(AP_start,freq,t_refractory)
+                blocked = self.is_blocked(AP_start, freq, t_refractory)
                 n_APs = self.count_APs(vm_key) - 1
-                if n_APs<0:
+                if n_APs < 0:
                     n_APs = 0
                 onset = n_APs > 0
 
-                axon_state = { 'is_blocked':blocked,
-                                'has_onset':onset,
-                                'n_onset':n_APs}
+                axon_state = {
+                    "is_blocked": blocked,
+                    "has_onset": onset,
+                    "n_onset": n_APs,
+                }
                 self.update(axon_state)
             else:
-                rise_warning("The following keys are missing.", required_keys - set(self.keys()), " Please check the simulation parameters")
+                rise_warning(
+                    "The following keys are missing.",
+                    required_keys - set(self.keys()),
+                    " Please check the simulation parameters",
+                )
                 return None
-                        
+
         else:
-            axon_state = { 'is_blocked':self.is_blocked,
-                            'has_onset':self.has_onset,
-                            'n_onset':self.n_onset} 
+            axon_state = {
+                "is_blocked": self.is_blocked,
+                "has_onset": self.has_onset,
+                "n_onset": self.n_onset,
+            }
         return axon_state
 
     ##################################
@@ -1465,7 +1557,9 @@ def compute_f_mem(self):
         """
 
         if "g_mem" not in self:
-            rise_warning("f_mem cannot be computed computed without membrane conductivity")
+            rise_warning(
+                "f_mem cannot be computed computed without membrane conductivity"
+            )
             return None
         if "f_mem" not in self:
             ax = self.generate_axon()
@@ -1481,11 +1575,16 @@ def compute_f_mem(self):
         self["f_mem"] = to_nrv_unit(f_mem, "MHz")
         return self["f_mem"]
 
-
-    def get_membrane_conductivity(self, x:float|None=0, t:float|None=0, unit:str="S/cm**2", mem_th:float=7*nm)->float:
+    def get_membrane_conductivity(
+        self,
+        x: float | None = 0,
+        t: float | None = 0,
+        unit: str = "S/cm**2",
+        mem_th: float = 7 * nm,
+    ) -> float:
         """
         get the membrane conductivity at a position x and a time t
-    
+
 
         Parameters
         ----------
@@ -1510,11 +1609,11 @@ def get_membrane_conductivity(self, x:float|None=0, t:float|None=0, unit:str="S/
             return None
 
         n_t = len(self["g_mem"][0])
-        n_x = len(self["g_mem"][:,0])
+        n_x = len(self["g_mem"][:, 0])
         if t is None:
             i_t = np.arange(n_t)
         else:
-            i_t = int(n_t*t/self["t_sim"])
+            i_t = int(n_t * t / self["t_sim"])
         if x is None:
             i_x = np.arange(n_x)
         else:
@@ -1529,8 +1628,9 @@ def get_membrane_conductivity(self, x:float|None=0, t:float|None=0, unit:str="S/
             g *= from_nrv_unit(mem_th, "cm")
             return convert(g, "S/cm", unit)
 
-
-    def get_membrane_capacitance(self, unit:str="uF/cm**2", mem_th:float=7*nm)->float:
+    def get_membrane_capacitance(
+        self, unit: str = "uF/cm**2", mem_th: float = 7 * nm
+    ) -> float:
         """
         get the axon membrane capacitance or permitivity
 
@@ -1558,7 +1658,14 @@ def get_membrane_capacitance(self, unit:str="uF/cm**2", mem_th:float=7*nm)->floa
             c_mem *= from_nrv_unit(mem_th, "cm")
             return convert(c_mem, "S/cm", unit)
 
-    def get_membrane_complexe_admitance(self, f:float=1., x:float=0, t:float=0, unit:str="S/m", mem_th:float=7*nm)->np.array:
+    def get_membrane_complexe_admitance(
+        self,
+        f: float = 1.0,
+        x: float = 0,
+        t: float = 0,
+        unit: str = "S/m",
+        mem_th: float = 7 * nm,
+    ) -> np.array:
         """
         get the membran complexe admitance of each axon at a position x and a time t for a given frequency
 
@@ -1577,7 +1684,7 @@ def get_membrane_complexe_admitance(self, f:float=1., x:float=0, t:float=0, unit
         """
         c = self.get_membrane_capacitance(mem_th=mem_th)
         g = self.get_membrane_conductivity(x=x, t=t, mem_th=mem_th)
-        f_mem = g/(2*np.pi*c)
+        f_mem = g / (2 * np.pi * c)
 
         # in [MHz] as g_mem in [S/cm^{2}] and c_mem [uF/cm^{2}]
         # [MHz] to convert to [kHz]
@@ -1592,12 +1699,14 @@ def get_membrane_complexe_admitance(self, f:float=1., x:float=0, t:float=0, unit
             Y *= from_nrv_unit(mem_th, "cm")
             return convert(Y, "S/cm", unit)
 
-    def get_membrane_material(self, t:float=0, unit:str="S/m", mem_th:float=7*nm, **interp_kwargs)->f_material:
+    def get_membrane_material(
+        self, t: float = 0, unit: str = "S/m", mem_th: float = 7 * nm, **interp_kwargs
+    ) -> f_material:
 
         n_t = len(self["g_mem"][0])
-        i_t = int(n_t*t/self["t_sim"])
+        i_t = int(n_t * t / self["t_sim"])
         x_ = self["x_rec"]
-        g_ = deepcopy(self["g_mem"][:,i_t])
+        g_ = deepcopy(self["g_mem"][:, i_t])
 
         # Surface conductivity in [S]/([m]*[m])
         if "2" in unit:
@@ -1612,28 +1721,39 @@ def get_membrane_material(self, t:float=0, unit:str="S/m", mem_th:float=7*nm, **
     ## Ploting methods ##
     #####################
 
-    def raster_plot(self, axes: plt.axes, key:str="V_mem",**kwgs)->None:
+    def raster_plot(self, axes: plt.axes, key: str = "V_mem", **kwgs) -> None:
         required_keys = {key, "tstop", "L"}
         if required_keys in self:
             self.rasterize(key)
-            axes.scatter(self[key+"_raster_time"], self[key+"_raster_x_position"], **kwgs)
+            axes.scatter(
+                self[key + "_raster_time"], self[key + "_raster_x_position"], **kwgs
+            )
             axes.set_xlim(0, self["tstop"])
             axes.set_ylim(0, self["L"])
         else:
-            rise_warning("The following keys are missing.", required_keys - set(self.keys()), " Please check the simulation parameters")
-
-
-    def colormap_plot(self, axes: plt.axes, key:str="V_mem",**kwgs)->plt.colorbar:
-        required_keys = {key, "tstop", "L","t"}
+            rise_warning(
+                "The following keys are missing.",
+                required_keys - set(self.keys()),
+                " Please check the simulation parameters",
+            )
+
+    def colormap_plot(self, axes: plt.axes, key: str = "V_mem", **kwgs) -> plt.colorbar:
+        required_keys = {key, "tstop", "L", "t"}
         if required_keys in self:
-            map = axes.pcolormesh(self['t'], self.get_axon_xrec(), self[key] ,shading='auto', **kwgs)
-            axes.set_xlabel('Time (ms)')
-            axes.set_ylabel('Position (µm)')
+            map = axes.pcolormesh(
+                self["t"], self.get_axon_xrec(), self[key], shading="auto", **kwgs
+            )
+            axes.set_xlabel("Time (ms)")
+            axes.set_ylabel("Position (µm)")
             axes.set_xlim(0, self["tstop"])
             axes.set_ylim(0, self["L"])
             cbar = plt.colorbar(map)
             cbar.set_label(key)
-            return(cbar)
+            return cbar
         else:
-            rise_warning("The following keys are missing.", required_keys - set(self.keys()), " Please check the simulation parameters")
-        return(None)
\ No newline at end of file
+            rise_warning(
+                "The following keys are missing.",
+                required_keys - set(self.keys()),
+                " Please check the simulation parameters",
+            )
+        return None
diff --git a/nrv/nmod/results/fascicles_results.py b/nrv/nmod/results/_fascicles_results.py
similarity index 60%
rename from nrv/nmod/results/fascicles_results.py
rename to nrv/nmod/results/_fascicles_results.py
index 7088f153..1fb85133 100644
--- a/nrv/nmod/results/fascicles_results.py
+++ b/nrv/nmod/results/_fascicles_results.py
@@ -2,27 +2,26 @@
 NRV-:class:`.fascicle_results` handling.
 """
 
-
-from ...backend.NRV_Results import sim_results
-from ...backend.log_interface import pass_info, rise_warning, rise_error
-from ...backend.MCore import MCH
-from ...fmod.electrodes import is_FEM_electrode
-from ...utils.units import nm, convert, from_nrv_unit, to_nrv_unit
-from ...utils.misc import membrane_capacitance_from_model, compute_complex_admitance
+from ...backend._NRV_Results import sim_results
+from ...backend._log_interface import pass_info, rise_warning, rise_error
+from ...backend._MCore import MCH
+from ...fmod._electrodes import is_FEM_electrode
+from ...utils._units import nm, convert, from_nrv_unit, to_nrv_unit
+from ...utils._misc import membrane_capacitance_from_model, compute_complex_admitance
 import matplotlib.pyplot as plt
 import numpy as np
 
 
-
 def number_in_str(s: str) -> bool:
     return any(i.isdigit() for i in s)
 
-recognized_axon_types = ['all','myelinated','unmyelinated']
+
+recognized_axon_types = ["all", "myelinated", "unmyelinated"]
+
+
 class fascicle_results(sim_results):
-    """
+    """ """
 
-    
-    """
     def __init__(self, context=None):
         super().__init__(context)
 
@@ -32,30 +31,31 @@ def n_ax(self):
         Number of axons in the fascicle
         """
         return len(self.axons_diameter)
-    
-    
-    def get_n_ax(self, ax_type:str = 'all') -> int:
-        """
-        Number of myelinated axons in the fascicle
-        """
-        return(len(self.get_axons_key(ax_type)))
 
-    def get_axons_key(self, ax_type:str = 'all') -> list:
+    def get_n_ax(self, ax_type: str = "all") -> int:
         """
-
+        Number of myelinated axons in the fascicle
         """
-        if (ax_type not in recognized_axon_types):
-            rise_error(f"Axon type specified not recognized. Recognized types are: {recognized_axon_types}")
+        return len(self.get_axons_key(ax_type))
+
+    def get_axons_key(self, ax_type: str = "all") -> list:
+        """ """
+        if ax_type not in recognized_axon_types:
+            rise_error(
+                f"Axon type specified not recognized. Recognized types are: {recognized_axon_types}"
+            )
         all_keys = self.keys()
-        axon_keys = [ i for i in all_keys if ("axon" in i and number_in_str(i)) ]
-        if ax_type != 'all':
-            if ax_type == 'unmyelinated':
-                axon_keys = [ i for i in axon_keys if self[i].myelinated == False]
+        axon_keys = [i for i in all_keys if ("axon" in i and number_in_str(i))]
+        if ax_type != "all":
+            if ax_type == "unmyelinated":
+                axon_keys = [i for i in axon_keys if self[i].myelinated == False]
             else:
-                axon_keys = [ i for i in axon_keys if self[i].myelinated == True]
-        return(axon_keys)
+                axon_keys = [i for i in axon_keys if self[i].myelinated == True]
+        return axon_keys
 
-    def get_recruited_axons(self, ax_type:str = 'all', normalize:bool=False) -> int|float:
+    def get_recruited_axons(
+        self, ax_type: str = "all", normalize: bool = False
+    ) -> int | float:
         """
         Return the number or the ratio of recruited axons in the fascicle
 
@@ -77,13 +77,15 @@ def get_recruited_axons(self, ax_type:str = 'all', normalize:bool=False) -> int|
         axons_keys = self.get_axons_key(ax_type)
         n_recr = 0
         for axon in axons_keys:
-            if (self[axon].is_recruited()):
-                n_recr+=1
+            if self[axon].is_recruited():
+                n_recr += 1
         if normalize:
             n_recr /= self.get_n_ax(ax_type)
         return n_recr
 
-    def get_recruited_axons_greater_than(self, diam:float, ax_type:str = 'all', normalize:bool=False) -> float:
+    def get_recruited_axons_greater_than(
+        self, diam: float, ax_type: str = "all", normalize: bool = False
+    ) -> float:
         """
         Return the number or the ratio of recruited axons with a diameter greater than `diam` in the fascicle
 
@@ -106,15 +108,17 @@ def get_recruited_axons_greater_than(self, diam:float, ax_type:str = 'all', norm
         n_recr = 0
         n_tot = 0
         for axon in axons_keys:
-            if self[axon].diameter>diam:
+            if self[axon].diameter > diam:
                 n_tot += 1
-                if (self[axon].is_recruited()):
+                if self[axon].is_recruited():
                     n_recr += 1
         if normalize:
             n_recr /= n_tot
         return n_recr
 
-    def get_recruited_axons_lesser_than(self, diam:float, ax_type:str = 'all', normalize:bool=False) -> float:
+    def get_recruited_axons_lesser_than(
+        self, diam: float, ax_type: str = "all", normalize: bool = False
+    ) -> float:
         """
         Return the number or the ratio of recruited axons with a diameter smaller than `diam` in the fascicle
 
@@ -137,39 +141,41 @@ def get_recruited_axons_lesser_than(self, diam:float, ax_type:str = 'all', norma
         n_recr = 0
         n_tot = 0
         for axon in axons_keys:
-            if self[axon].diameter<diam:
+            if self[axon].diameter < diam:
                 n_tot += 1
-                if (self[axon].is_recruited()):
+                if self[axon].is_recruited():
                     n_recr += 1
         if normalize:
             n_recr /= n_tot
         return n_recr
 
-    def get_axons(self) -> list: 
+    def get_axons(self) -> list:
         axons_keys = self.get_axons_key()
         axon_diam = []
         axon_type = []
         axon_y = []
         axon_z = []
-        axon_recruited = [] 
+        axon_recruited = []
         for axon in axons_keys:
             axon_recruited.append(self[axon].is_recruited())
             axon_y.append(self[axon].y)
             axon_z.append(self[axon].z)
             axon_diam.append(self[axon].diameter)
             axon_type.append(self[axon].myelinated)
-        return(axon_diam,axon_type,axon_y,axon_z,axon_recruited)
-    
-    def get_block_summary_axons(self,AP_start:float, freq:float=None, t_refractory:float = 1) -> list:
+        return (axon_diam, axon_type, axon_y, axon_z, axon_recruited)
+
+    def get_block_summary_axons(
+        self, AP_start: float, freq: float = None, t_refractory: float = 1
+    ) -> list:
         axons_keys = self.get_axons_key()
         axon_diam = []
         axon_type = []
         axon_y = []
         axon_z = []
-        is_blocked = [] 
-        n_onset = [] 
+        is_blocked = []
+        n_onset = []
         for axon in axons_keys:
-            self[axon].block_summary(AP_start,freq,t_refractory)
+            self[axon].block_summary(AP_start, freq, t_refractory)
 
             is_blocked.append(self[axon].is_blocked)
             n_onset.append(self[axon].n_onset)
@@ -177,10 +183,12 @@ def get_block_summary_axons(self,AP_start:float, freq:float=None, t_refractory:f
             axon_z.append(self[axon].z)
             axon_diam.append(self[axon].diameter)
             axon_type.append(self[axon].myelinated)
-        return(axon_diam,axon_type,axon_y,axon_z,is_blocked,n_onset)
+        return (axon_diam, axon_type, axon_y, axon_z, is_blocked, n_onset)
 
     # impeddance related methods
-    def get_membrane_conductivity(self, x:float=0, t:float=0, unit:str="S/cm**2", mem_th:float=7*nm)->np.array:
+    def get_membrane_conductivity(
+        self, x: float = 0, t: float = 0, unit: str = "S/cm**2", mem_th: float = 7 * nm
+    ) -> np.array:
         """
         get the membran conductivity of each axon at a position x and a time t
 
@@ -208,13 +216,14 @@ def get_membrane_conductivity(self, x:float=0, t:float=0, unit:str="S/cm**2", me
         for key in a_keys:
             g_ = self[key].get_membrane_conductivity(x=x, t=t, unit=unit, mem_th=mem_th)
             if g_ is not None:
-                g = np.concatenate((g,[g_]))
+                g = np.concatenate((g, [g_]))
             else:
                 return None
         return g
 
-
-    def get_membrane_capacitance(self, unit:str="uF/cm**2", mem_th:float=7*nm)->tuple[float]:
+    def get_membrane_capacitance(
+        self, unit: str = "uF/cm**2", mem_th: float = 7 * nm
+    ) -> tuple[float]:
         """
         get the membrane capacitance or permitivity of unmyelinated and myelinated axons filling the ner
 
@@ -244,7 +253,14 @@ def get_membrane_capacitance(self, unit:str="uF/cm**2", mem_th:float=7*nm)->tupl
             m_c_mem *= from_nrv_unit(mem_th, "cm")
             return convert(u_c_mem, "S/cm", unit), convert(m_c_mem, "S/cm", unit)
 
-    def get_membrane_complexe_admitance(self, f:float=1., x:float=0, t:float=0, unit:str="S/m", mem_th:float=7*nm)->np.array:
+    def get_membrane_complexe_admitance(
+        self,
+        f: float = 1.0,
+        x: float = 0,
+        t: float = 0,
+        unit: str = "S/m",
+        mem_th: float = 7 * nm,
+    ) -> np.array:
         """
         get the membran complexe admitance of each axon at a position x and a time t for a given frequency
 
@@ -264,7 +280,7 @@ def get_membrane_complexe_admitance(self, f:float=1., x:float=0, t:float=0, unit
         u_c, m_c = self.get_membrane_capacitance(mem_th=mem_th)
         eps = (self.axons_type * (m_c - u_c)) + u_c
         g = self.get_membrane_conductivity(x=x, t=t, mem_th=mem_th)
-        f_mem = g/(2*np.pi*eps)
+        f_mem = g / (2 * np.pi * eps)
 
         # in [MHz] as g_mem in [S/cm^{2}] and c_mem [uF/cm^{2}]
         # [MHz] to convert to [kHz]
@@ -278,9 +294,14 @@ def get_membrane_complexe_admitance(self, f:float=1., x:float=0, t:float=0, unit
         else:
             Y *= from_nrv_unit(mem_th, "cm")
             return convert(Y, "S/cm", unit)
-        
-    def get_block_summary (self, AP_start:float, freq:float=None, t_refractory_m:float = 1, t_refractory_um:float = 1) -> None:
-        
+
+    def get_block_summary(
+        self,
+        AP_start: float,
+        freq: float = None,
+        t_refractory_m: float = 1,
+        t_refractory_um: float = 1,
+    ) -> None:
         """
         Get block characteristics (blocked, onset response, number of APs) for each axon of the fascicle
 
@@ -298,43 +319,85 @@ def get_block_summary (self, AP_start:float, freq:float=None, t_refractory_m:flo
         axons_keys = self.get_axons_key()
         for axon in axons_keys:
             if self[axon].myelinated == True:
-                self[axon].block_summary(AP_start,freq,t_refractory_m)
+                self[axon].block_summary(AP_start, freq, t_refractory_m)
             else:
-                self[axon].block_summary(AP_start,freq,t_refractory_um)
+                self[axon].block_summary(AP_start, freq, t_refractory_um)
 
     ## Representation methods
     def plot_recruited_fibers(
-        self, axes:plt.axes, contour_color:str="k", myel_color:str="r", unmyel_color:str="b", num:bool=False
+        self,
+        axes: plt.axes,
+        contour_color: str = "k",
+        myel_color: str = "r",
+        unmyel_color: str = "b",
+        num: bool = False,
     ) -> None:
         if MCH.do_master_only_work():
             ## plot contour
-            axes.add_patch(plt.Circle((self.y_grav_center, self.z_grav_center),self.D/2,
-                                        color=contour_color,fill=False,linewidth=2,))
+            axes.add_patch(
+                plt.Circle(
+                    (self.y_grav_center, self.z_grav_center),
+                    self.D / 2,
+                    color=contour_color,
+                    fill=False,
+                    linewidth=2,
+                )
+            )
             ## plot axons
-            axon_diam,axon_type,axon_y,axon_z,axon_recruited = self.get_axons()
-            for k,_ in enumerate(axon_diam):
+            axon_diam, axon_type, axon_y, axon_z, axon_recruited = self.get_axons()
+            for k, _ in enumerate(axon_diam):
                 color = unmyel_color
                 if axon_type[k]:
                     color = myel_color
                 alpha = 0.1
-                if (axon_recruited[k]):
+                if axon_recruited[k]:
                     alpha = 1
-                axes.add_patch(plt.Circle((axon_y[k], axon_z[k]),axon_diam[k] / 2,
-                                color=color,fill=True,alpha = alpha,))
+                axes.add_patch(
+                    plt.Circle(
+                        (axon_y[k], axon_z[k]),
+                        axon_diam[k] / 2,
+                        color=color,
+                        fill=True,
+                        alpha=alpha,
+                    )
+                )
 
             if self.extra_stim is not None:
                 self.extra_stim.plot(axes=axes, color="gold", nerve_d=self.D)
             if num:
                 for k in range(self.n_ax):
-                    axes.text(self.axons_y[k], self.axons_z[k], str(k),horizontalalignment='center',verticalalignment='center')
-            axes.set_xlim((-1.1*self.D/2+self.y_grav_center, 1.1*self.D/2+self.y_grav_center))
-            axes.set_ylim((-1.1*self.D/2+self.z_grav_center, 1.1*self.D/2+self.z_grav_center))
-    
-    def plot_block_summary( self, axes:plt.axes,AP_start:float, freq:float=None, 
-                           t_refractory:float = 1, contour_color:str="k", num:bool=False) -> None:
+                    axes.text(
+                        self.axons_y[k],
+                        self.axons_z[k],
+                        str(k),
+                        horizontalalignment="center",
+                        verticalalignment="center",
+                    )
+            axes.set_xlim(
+                (
+                    -1.1 * self.D / 2 + self.y_grav_center,
+                    1.1 * self.D / 2 + self.y_grav_center,
+                )
+            )
+            axes.set_ylim(
+                (
+                    -1.1 * self.D / 2 + self.z_grav_center,
+                    1.1 * self.D / 2 + self.z_grav_center,
+                )
+            )
+
+    def plot_block_summary(
+        self,
+        axes: plt.axes,
+        AP_start: float,
+        freq: float = None,
+        t_refractory: float = 1,
+        contour_color: str = "k",
+        num: bool = False,
+    ) -> None:
         """
         plot the block_summary of the fascicle in the Y-Z plane (transverse section)
-        Color code: 
+        Color code:
         Green: fiber is blocked without any onset
         Blue: fiber is blocked with some onset
         Red: fiber is not blocked but has onset
@@ -361,43 +424,72 @@ def plot_block_summary( self, axes:plt.axes,AP_start:float, freq:float=None,
 
         if MCH.do_master_only_work():
             ## plot contour
-            axes.add_patch(plt.Circle((self.y_grav_center, self.z_grav_center),self.D/2,
-                                        color=contour_color,fill=False,linewidth=2,))
+            axes.add_patch(
+                plt.Circle(
+                    (self.y_grav_center, self.z_grav_center),
+                    self.D / 2,
+                    color=contour_color,
+                    fill=False,
+                    linewidth=2,
+                )
+            )
             ## plot axons
-            axon_diam,_,axon_y,axon_z,is_blocked,n_onset = self.get_block_summary_axons(AP_start=AP_start,freq=freq,t_refractory=t_refractory)
-            alpha_g = 1/np.max(n_onset)
-
-            #cmap = plt.get_cmap('viridis')
-            #norm = plt.Normalize(min(n_onset), max(n_onset))
-            #line_colors = cmap((n_onset))
-
-            for k,_ in enumerate(axon_diam):
+            axon_diam, _, axon_y, axon_z, is_blocked, n_onset = (
+                self.get_block_summary_axons(
+                    AP_start=AP_start, freq=freq, t_refractory=t_refractory
+                )
+            )
+            alpha_g = 1 / np.max(n_onset)
+
+            # cmap = plt.get_cmap('viridis')
+            # norm = plt.Normalize(min(n_onset), max(n_onset))
+            # line_colors = cmap((n_onset))
+
+            for k, _ in enumerate(axon_diam):
                 if is_blocked[k] is not True:
                     if n_onset[k] == 0:
                         c = "grey"
                         alpha = 0.5
                     else:
-                        c = "orangered" 
-                        alpha = n_onset[k]*alpha_g   
+                        c = "orangered"
+                        alpha = n_onset[k] * alpha_g
                     if is_blocked[k] is None:
-                        axes.scatter(axon_y[k], axon_z[k], marker =  'x', s = 20, c = 'k')
+                        axes.scatter(axon_y[k], axon_z[k], marker="x", s=20, c="k")
 
                 else:
                     if n_onset[k] == 0:
                         c = "seagreen"
                         alpha = 1
                     else:
-                        c = "steelblue" 
-                        alpha = n_onset[k]*alpha_g   
-            
-                axes.add_patch(plt.Circle((axon_y[k], axon_z[k]),axon_diam[k] / 2,
-                                color=c,fill=True,alpha = alpha,))
+                        c = "steelblue"
+                        alpha = n_onset[k] * alpha_g
+
+                axes.add_patch(
+                    plt.Circle(
+                        (axon_y[k], axon_z[k]),
+                        axon_diam[k] / 2,
+                        color=c,
+                        fill=True,
+                        alpha=alpha,
+                    )
+                )
 
             if self.extra_stim is not None:
                 self.extra_stim.plot(axes=axes, color="gold", nerve_d=self.D)
             if num:
                 for k in range(self.n_ax):
-                    axes.text(self.axons_y[k], self.axons_z[k], str(k))#horizontalalignment='center',verticalalignment='center')
-            axes.set_xlim((-1.1*self.D/2+self.y_grav_center, 1.1*self.D/2+self.y_grav_center))
-            axes.set_ylim((-1.1*self.D/2+self.z_grav_center, 1.1*self.D/2+self.z_grav_center))
-    
+                    axes.text(
+                        self.axons_y[k], self.axons_z[k], str(k)
+                    )  # horizontalalignment='center',verticalalignment='center')
+            axes.set_xlim(
+                (
+                    -1.1 * self.D / 2 + self.y_grav_center,
+                    1.1 * self.D / 2 + self.y_grav_center,
+                )
+            )
+            axes.set_ylim(
+                (
+                    -1.1 * self.D / 2 + self.z_grav_center,
+                    1.1 * self.D / 2 + self.z_grav_center,
+                )
+            )
diff --git a/nrv/nmod/results/myelinated_results.py b/nrv/nmod/results/_myelinated_results.py
similarity index 74%
rename from nrv/nmod/results/myelinated_results.py
rename to nrv/nmod/results/_myelinated_results.py
index 91e064a2..67cb990e 100644
--- a/nrv/nmod/results/myelinated_results.py
+++ b/nrv/nmod/results/_myelinated_results.py
@@ -4,20 +4,21 @@
 
 import numpy as np
 import matplotlib.pyplot as plt
-from .axons_results import axon_results
-from ..myelinated import myelinated
-from ...backend.log_interface import rise_warning
-from ...fmod.materials import is_mat, load_material
-from ...utils.units import to_nrv_unit, convert
+from ._axons_results import axon_results
+from ...backend._log_interface import rise_warning
+from ...fmod._materials import is_mat, load_material
+from ...utils._units import to_nrv_unit, convert
+
 
 class myelinated_results(axon_results):
-    """
+    """ """
 
-    """
     def __init__(self, context=None):
         super().__init__(context)
 
     def generate_axon(self):
+        if "myelinated" not in globals():
+            from .._myelinated import myelinated
         return myelinated(**self)
 
     def get_index_myelinated_sequence(self, n):
@@ -50,8 +51,6 @@ def get_index_myelinated_sequence(self, n):
             else:
                 return seq_types[((n - 1) // Nseg_per_sec) % N_sec_type]
 
-
-
     def find_central_node_coordinate(self):
         """
         Returns the index of the closer node from the center
@@ -84,7 +83,6 @@ def find_central_node_index(self):
         rise_warning("No node found in the axon")
         return n_center
 
-
     def get_myelin_properties(self, endo_mat=None):
         """
         compute the cutoff frequency of the axon's membrane and add it to the simulation results dictionnary
@@ -108,8 +106,8 @@ def get_myelin_properties(self, endo_mat=None):
         if endo_mat is not None:
             if not is_mat(endo_mat):
                 endo_mat = load_material(endo_mat)
-            I = np.isclose(self["g_mye"], 1e+10)
-            self["g_mye"][I] *= 0.
+            I = np.isclose(self["g_mye"], 1e10)
+            self["g_mye"][I] *= 0.0
             self["g_mye"][I] += convert(endo_mat.sigma, "S/m**2", "S/cm**2")
         self["c_mye"] = ax.get_myelin_capacitance()
         self["f_mye"] = self["g_mye"] / (2 * np.pi * self["c_mye"])
@@ -119,23 +117,33 @@ def get_myelin_properties(self, endo_mat=None):
         self["f_mye"] = to_nrv_unit(self["f_mye"], "MHz")
         return self["g_mye"], self["c_mye"], self["f_mye"]
 
-
-    def plot_x_t(self, axes: plt.axes, key:str="V_mem", color: str="k",**kwgs)->None:
+    def plot_x_t(
+        self, axes: plt.axes, key: str = "V_mem", color: str = "k", **kwgs
+    ) -> None:
         node_x = self.x[self.node_index]
-        dx = np.abs(node_x[1]-node_x[0])
+        dx = np.abs(node_x[1] - node_x[0])
         rec_idx = self.node_index
         if not "ALL" in self.rec.upper():
             rec_idx = np.arange(len(node_x))
-        norm_fac = dx/(np.max(abs(self[key]))*1.1)
-        offset = np.abs(np.min(self[key][0]*norm_fac))
-        for node,node_idx in zip(node_x,rec_idx):
+        norm_fac = dx / (np.max(abs(self[key])) * 1.1)
+        offset = np.abs(np.min(self[key][0] * norm_fac))
+        for node, node_idx in zip(node_x, rec_idx):
             axes.plot(
-                self["t"], self[key][node_idx]*norm_fac + node + offset, color=color, **kwgs
+                self["t"],
+                self[key][node_idx] * norm_fac + node + offset,
+                color=color,
+                **kwgs
             )
 
+    def colormap_plot(self, axes: plt.axes, key: str = "V_mem", **kwgs) -> plt.colorbar:
+        if self.rec == "all":
+            return super().colormap_plot(axes, key, **kwgs)
+        else: 
+            rise_warning("colormap_plot be myelined.rec is not 'all'")
+            return None
+    
 
-
-    def plot_Nav_states(ax: plt.axes) ->None:
+    def plot_Nav_states(ax: plt.axes) -> None:
         """
         Plot the state machine for kinetic (Markov) Nav 1.1 to 1.9 values
 
@@ -164,12 +172,26 @@ def plot_Nav_states(ax: plt.axes) ->None:
         )
         ax.text(-2, 0.2, "$I_2I_1$", ha="center", va="center", alpha=0.4)
         ax.arrow(
-            -1.5, -0.03, -1, 0, linewidth=1, alpha=0.5, head_width=0.02, head_length=0.02
+            -1.5,
+            -0.03,
+            -1,
+            0,
+            linewidth=1,
+            alpha=0.5,
+            head_width=0.02,
+            head_length=0.02,
         )
         ax.text(-2, -0.2, "$I_1I_2$", ha="center", va="center", alpha=0.4)
 
         ax.arrow(
-            -0.83, 0.25, 0.5, 0.5, linewidth=1, alpha=0.5, head_width=0.02, head_length=0.02
+            -0.83,
+            0.25,
+            0.5,
+            0.5,
+            linewidth=1,
+            alpha=0.5,
+            head_width=0.02,
+            head_length=0.02,
         )
         ax.text(-0.9, 0.6, "$I_1C_1$", ha="center", va="center", alpha=0.4)
         ax.arrow(
@@ -185,11 +207,25 @@ def plot_Nav_states(ax: plt.axes) ->None:
         ax.text(-0.45, 0.25, r"$C_1I_1$", ha="center", va="center", alpha=0.4)
 
         ax.arrow(
-            0.72, 0.25, -0.5, 0.5, linewidth=1, alpha=0.5, head_width=0.02, head_length=0.02
+            0.72,
+            0.25,
+            -0.5,
+            0.5,
+            linewidth=1,
+            alpha=0.5,
+            head_width=0.02,
+            head_length=0.02,
         )
         ax.text(0.9, 0.6, r"$C_1C_2$", ha="center", va="center", alpha=0.4)
         ax.arrow(
-            0.33, 0.75, 0.5, -0.5, linewidth=1, alpha=0.5, head_width=0.02, head_length=0.02
+            0.33,
+            0.75,
+            0.5,
+            -0.5,
+            linewidth=1,
+            alpha=0.5,
+            head_width=0.02,
+            head_length=0.02,
         )
         ax.text(0.45, 0.25, r"$C_2C_1$", ha="center", va="center", alpha=0.4)
 
@@ -205,7 +241,14 @@ def plot_Nav_states(ax: plt.axes) ->None:
         )
         ax.text(0.9, -0.6, r"$C_2O_1$", ha="center", va="center", alpha=0.4)
         ax.arrow(
-            0.22, -0.75, 0.5, 0.5, linewidth=1, alpha=0.5, head_width=0.02, head_length=0.02
+            0.22,
+            -0.75,
+            0.5,
+            0.5,
+            linewidth=1,
+            alpha=0.5,
+            head_width=0.02,
+            head_length=0.02,
         )
         ax.text(0.45, -0.25, r"$O_1C_2$", ha="center", va="center", alpha=0.4)
 
@@ -221,7 +264,9 @@ def plot_Nav_states(ax: plt.axes) ->None:
         )
         ax.text(-0.9, -0.6, r"$O_1I_1$", ha="center", va="center", alpha=0.4)
 
-        ax.arrow(1.5, 0.03, 1, 0, linewidth=1, alpha=0.5, head_width=0.02, head_length=0.02)
+        ax.arrow(
+            1.5, 0.03, 1, 0, linewidth=1, alpha=0.5, head_width=0.02, head_length=0.02
+        )
         ax.text(2, 0.2, r"$C_20_2$", ha="center", va="center", alpha=0.4)
         ax.arrow(
             2.5, -0.03, -1, 0, linewidth=1, alpha=0.5, head_width=0.02, head_length=0.02
@@ -230,4 +275,4 @@ def plot_Nav_states(ax: plt.axes) ->None:
         # make axes to disappear
         ax.set_xticks([])
         ax.set_yticks([])
-        ax.axis("off")
\ No newline at end of file
+        ax.axis("off")
diff --git a/nrv/nmod/results/nerve_results.py b/nrv/nmod/results/_nerve_results.py
similarity index 57%
rename from nrv/nmod/results/nerve_results.py
rename to nrv/nmod/results/_nerve_results.py
index cc64fb58..7f54c0ef 100644
--- a/nrv/nmod/results/nerve_results.py
+++ b/nrv/nmod/results/_nerve_results.py
@@ -2,14 +2,13 @@
 NRV-:class:`.nerve_results` handling.
 """
 
-
-from ...backend.NRV_Results import sim_results
-from .fascicles_results import fascicle_results
-from .axons_results import axon_results
-from ...backend.log_interface import rise_error, rise_warning, pass_info
-from ...backend.MCore import MCH
-from ...utils.units import nm, convert, from_nrv_unit
-from ...utils.misc import membrane_capacitance_from_model
+from ...backend._NRV_Results import sim_results
+from ._fascicles_results import fascicle_results
+from ._axons_results import axon_results
+from ...backend._log_interface import rise_error, rise_warning, pass_info
+from ...backend._MCore import MCH
+from ...utils._units import nm, convert, from_nrv_unit
+from ...utils._misc import membrane_capacitance_from_model
 
 
 import matplotlib.pyplot as plt
@@ -19,17 +18,15 @@
 def number_in_str(s: str) -> bool:
     return any(i.isdigit() for i in s)
 
-class nerve_results(sim_results):
-    """
 
-    """
+class nerve_results(sim_results):
+    """ """
 
     def __init__(self, context=None):
         super().__init__(context)
 
-
     @property
-    def fascicle_keys(self)->list:
+    def fascicle_keys(self) -> list:
         """
         Number of fascicles in the fascicle
         """
@@ -37,14 +34,14 @@ def fascicle_keys(self)->list:
         return [i for i in all_keys if ("fascicle" in i and number_in_str(i))]
 
     @property
-    def n_fasc(self)->int:
+    def n_fasc(self) -> int:
         """
         Number of fascicles in the fascicle
         """
         return len(self.fascicles)
 
     @property
-    def n_ax(self)->int:
+    def n_ax(self) -> int:
         """
         Number of axons in the fascicle
         """
@@ -54,9 +51,8 @@ def n_ax(self)->int:
             _n_ax += self[key].n_ax
         return _n_ax
 
-
     @property
-    def axons_type(self)->np.ndarray:
+    def axons_type(self) -> np.ndarray:
         """
         type of axons of each fascicles
 
@@ -71,11 +67,11 @@ def axons_type(self)->np.ndarray:
         for key in fasc_keys:
             fasc_mye = np.vstack(
                 (
-                    self[key].ID*np.ones(self[key].n_ax),
-                    self[key].axons_type, 
+                    self[key].ID * np.ones(self[key].n_ax),
+                    self[key].axons_type,
                 )
             )
-            _mye[:, _offset:_offset+self[key].n_ax] = fasc_mye.T
+            _mye[:, _offset : _offset + self[key].n_ax] = fasc_mye.T
             _offset += self[key].n_ax
         return _mye
 
@@ -85,7 +81,7 @@ def get_fascicle_results(self, ID: int) -> fascicle_results:
         else:
             return self[f"fascicle{ID}"]
 
-    def get_fascicle_results(self, fasc_ID: int, ax_ID:int) -> axon_results:
+    def get_fascicle_results(self, fasc_ID: int, ax_ID: int) -> axon_results:
         if fasc_ID not in self.fascicles_IDs:
             rise_error(f"Fascicle ID: {fasc_ID} does not exists.")
         else:
@@ -94,13 +90,14 @@ def get_fascicle_results(self, fasc_ID: int, ax_ID:int) -> axon_results:
             else:
                 return self[f"fascicle{fasc_ID}"][f"axon{ax_ID}"]
 
-    def get_fascicle_key(self) ->list:
+    def get_fascicle_key(self) -> list:
         all_keys = self.keys()
-        fascicle_keys = [ i for i in all_keys if ("fascicle" in i and number_in_str(i))]
-        return(fascicle_keys)
-
+        fascicle_keys = [i for i in all_keys if ("fascicle" in i and number_in_str(i))]
+        return fascicle_keys
 
-    def get_recruited_axons(self, ax_type:str = "all", normalize:bool=False) -> int|float:
+    def get_recruited_axons(
+        self, ax_type: str = "all", normalize: bool = False
+    ) -> int | float:
         """
         Return the number or the ratio of recruited axons in the nerve
 
@@ -129,9 +126,10 @@ def get_recruited_axons(self, ax_type:str = "all", normalize:bool=False) -> int|
             n_recr /= self.n_fasc
         return n_recr
 
-
     # impeddance related methods
-    def get_membrane_conductivity(self, x:float=0, t:float=0, unit:str="S/cm**2", mem_th:float=7*nm)->np.array:
+    def get_membrane_conductivity(
+        self, x: float = 0, t: float = 0, unit: str = "S/cm**2", mem_th: float = 7 * nm
+    ) -> np.array:
         """
         get the membran conductivity of each axon at a position x and a time t
 
@@ -159,43 +157,51 @@ def get_membrane_conductivity(self, x:float=0, t:float=0, unit:str="S/cm**2", me
         for key in f_keys:
             g_ = self[key].get_membrane_conductivity(x=x, t=t, unit=unit, mem_th=mem_th)
             if g_ is not None:
-                g = np.concatenate((g,g_))
+                g = np.concatenate((g, g_))
             else:
                 return None
         return g
 
-    def get_membrane_capacitance(self, unit:str="uF/cm**2", mem_th:float=7*nm)->tuple[float]:
-            """
-            get the membrane capacitance or permitivity of unmyelinated and myelinated axons filling the ner
-
-            Parameters
-            ----------
-            unit : str, optional
-                unit of the returned conductivity see `units`, by default "S/cm**2"
-            mem_th : float, optional
-                membrane thickness in um, by default 7*nm
-
-            Note
-            ----
-            depending of the unit parameter this function either return :
-
-                - the surface conductivity in [S]/([m]*[m]): from neuron simulation
-                - the conductivity in [S]/[m]:  by multiplying surface conductivity by membrane thickness
-            """
-            u_c_mem = membrane_capacitance_from_model(self.unmyelinated_param["model"])
-            m_c_mem = membrane_capacitance_from_model(self.myelinated_param["model"])
-
-            # Surface capacity in [F]/([m]*[m])
-            if "2" in unit:
-                return convert(u_c_mem, "S/cm**2", unit), convert(m_c_mem, "S/cm**2", unit)
-            # permitivity in [F]/[m]
-            else:
-                u_c_mem *= from_nrv_unit(mem_th, "cm")
-                m_c_mem *= from_nrv_unit(mem_th, "cm")
-                return convert(u_c_mem, "S/cm", unit), convert(m_c_mem, "S/cm", unit)
+    def get_membrane_capacitance(
+        self, unit: str = "uF/cm**2", mem_th: float = 7 * nm
+    ) -> tuple[float]:
+        """
+        get the membrane capacitance or permitivity of unmyelinated and myelinated axons filling the ner
+
+        Parameters
+        ----------
+        unit : str, optional
+            unit of the returned conductivity see `units`, by default "S/cm**2"
+        mem_th : float, optional
+            membrane thickness in um, by default 7*nm
 
+        Note
+        ----
+        depending of the unit parameter this function either return :
+
+            - the surface conductivity in [S]/([m]*[m]): from neuron simulation
+            - the conductivity in [S]/[m]:  by multiplying surface conductivity by membrane thickness
+        """
+        u_c_mem = membrane_capacitance_from_model(self.unmyelinated_param["model"])
+        m_c_mem = membrane_capacitance_from_model(self.myelinated_param["model"])
 
-    def get_membrane_complexe_admitance(self, f:float=1., x:float=0, t:float=0, unit:str="S/m", mem_th:float=7*nm)->np.array:
+        # Surface capacity in [F]/([m]*[m])
+        if "2" in unit:
+            return convert(u_c_mem, "S/cm**2", unit), convert(m_c_mem, "S/cm**2", unit)
+        # permitivity in [F]/[m]
+        else:
+            u_c_mem *= from_nrv_unit(mem_th, "cm")
+            m_c_mem *= from_nrv_unit(mem_th, "cm")
+            return convert(u_c_mem, "S/cm", unit), convert(m_c_mem, "S/cm", unit)
+
+    def get_membrane_complexe_admitance(
+        self,
+        f: float = 1.0,
+        x: float = 0,
+        t: float = 0,
+        unit: str = "S/m",
+        mem_th: float = 7 * nm,
+    ) -> np.array:
         """
         get the membran complexe admitance of each axon at a position x and a time t for a given frequency
 
@@ -215,30 +221,49 @@ def get_membrane_complexe_admitance(self, f:float=1., x:float=0, t:float=0, unit
         Y = []
         f_keys = self.get_fascicle_key()
         for key in f_keys:
-            Y_ = self[key].get_membrane_complexe_admitance(f=f, x=x, t=t, unit=unit, mem_th=mem_th)
+            Y_ = self[key].get_membrane_complexe_admitance(
+                f=f, x=x, t=t, unit=unit, mem_th=mem_th
+            )
             if Y_ is not None:
-                Y = np.concatenate((Y,Y_))
+                Y = np.concatenate((Y, Y_))
             else:
                 return None
         return Y
-    
+
     ## Representation methods
     def plot_recruited_fibers(
-        self, axes:plt.axes, contour_color:str="k", myel_color:str="r", unmyel_color:str="b", elec_color:str="gold",num:bool=False, **kwgs
+        self,
+        axes: plt.axes,
+        contour_color: str = "k",
+        myel_color: str = "r",
+        unmyel_color: str = "b",
+        elec_color: str = "gold",
+        num: bool = False,
+        **kwgs,
     ):
-        """
-
-        """
+        """ """
         if MCH.do_master_only_work():
             ## plot contour
-            axes.add_patch(plt.Circle((self.y_grav_center, self.z_grav_center),self.D/2,color=contour_color,
-                                fill=False,linewidth=4,))
+            axes.add_patch(
+                plt.Circle(
+                    (self.y_grav_center, self.z_grav_center),
+                    self.D / 2,
+                    color=contour_color,
+                    fill=False,
+                    linewidth=4,
+                )
+            )
             fasc_keys = self.get_fascicle_key()
             for key in fasc_keys:
                 fasc_res = self[key]
-                fasc_res.plot_recruited_fibers(axes=axes,contour_color="grey",
-                    myel_color=myel_color,unmyel_color=unmyel_color,num=num,)
+                fasc_res.plot_recruited_fibers(
+                    axes=axes,
+                    contour_color="grey",
+                    myel_color=myel_color,
+                    unmyel_color=unmyel_color,
+                    num=num,
+                )
             if self.extra_stim is not None:
                 self.extra_stim.plot(axes=axes, color=elec_color, nerve_d=self.D)
-            axes.set_xlim((-1.1*self.D/2, 1.1*self.D/2))
-            axes.set_ylim((-1.1*self.D/2, 1.1*self.D/2))
+            axes.set_xlim((-1.1 * self.D / 2, 1.1 * self.D / 2))
+            axes.set_ylim((-1.1 * self.D / 2, 1.1 * self.D / 2))
diff --git a/nrv/nmod/results/_unmyelinated_results.py b/nrv/nmod/results/_unmyelinated_results.py
new file mode 100644
index 00000000..71f53970
--- /dev/null
+++ b/nrv/nmod/results/_unmyelinated_results.py
@@ -0,0 +1,37 @@
+"""
+NRV-:class:`.unmyelinated_results` handling.
+"""
+
+import numpy as np
+import matplotlib.pyplot as plt
+from ._axons_results import axon_results
+
+
+class unmyelinated_results(axon_results):
+    """ """
+
+    def __init__(self, context=None):
+        super().__init__(context)
+
+    def generate_axon(self):
+        if "unmyelinated" not in globals():
+            from .._unmyelinated import unmyelinated
+        return unmyelinated(**self)
+
+    def plot_x_t(
+        self,
+        axes: plt.axes,
+        key: str = "V_mem",
+        color: str = "k",
+        n_lines: int = 20,
+        **kwgs
+    ) -> None:
+        x_index = np.int32(np.linspace(0, len(self.x_rec) - 1, n_lines))
+        x_pos = self.x_rec[x_index]
+        dx = np.abs(x_pos[1] - x_pos[0])
+        norm_fac = dx / (np.max(abs(self[key])) * 1.1)
+        offset = np.abs(np.min(self[key][0] * norm_fac))
+        for x, x_idx in zip(x_pos, x_index):
+            axes.plot(
+                self["t"], self[key][x_idx] * norm_fac + x + offset, color=color, **kwgs
+            )
diff --git a/nrv/nmod/results/unmyelinated_results.py b/nrv/nmod/results/unmyelinated_results.py
deleted file mode 100644
index d7c70ff1..00000000
--- a/nrv/nmod/results/unmyelinated_results.py
+++ /dev/null
@@ -1,31 +0,0 @@
-"""
-NRV-:class:`.unmyelinated_results` handling.
-"""
-
-import numpy as np
-import matplotlib.pyplot as plt
-from .axons_results import axon_results
-from ..unmyelinated import unmyelinated
-
-class unmyelinated_results(axon_results):
-    """
-
-    """
-    def __init__(self, context=None):
-        super().__init__(context)
-
-
-    def generate_axon(self):
-        return unmyelinated(**self)
-
-
-    def plot_x_t(self, axes: plt.axes, key:str="V_mem", color: str="k", n_lines:int=20,**kwgs)->None:
-        x_index = np.int32(np.linspace(0,len(self.x_rec)-1,n_lines))
-        x_pos = self.x_rec[x_index]
-        dx = np.abs(x_pos[1]-x_pos[0])
-        norm_fac = dx/(np.max(abs(self[key]))*1.1)
-        offset = np.abs(np.min(self[key][0]*norm_fac))
-        for x,x_idx in zip(x_pos,x_index):
-            axes.plot(
-                self["t"], self[key][x_idx]*norm_fac + x + offset, color=color, **kwgs
-            )
diff --git a/nrv/nrv2calm b/nrv/nrv2calm
index 147d866a..8bbdcb92 100755
--- a/nrv/nrv2calm
+++ b/nrv/nrv2calm
@@ -25,6 +25,7 @@ import time
 
 # import nrv
 from nrv import backend
+from nrv import parameters
 
 # test for possibility of parallel computing
 try:
@@ -69,7 +70,7 @@ machine_config = configparser.ConfigParser()
 if args.config != None:
     config_fname = args.config
 else:
-    config_fname = os.environ["NRVPATH"] + "/_misc/NRV.ini"
+    config_fname = parameters.nrv_path + "/_misc/NRV.ini"
 machine_config.read(config_fname)
 
 
diff --git a/nrv/optim/CostFunctions.py b/nrv/optim/_CostFunctions.py
similarity index 90%
rename from nrv/optim/CostFunctions.py
rename to nrv/optim/_CostFunctions.py
index da4f3a46..e77853ff 100644
--- a/nrv/optim/CostFunctions.py
+++ b/nrv/optim/_CostFunctions.py
@@ -1,11 +1,12 @@
 """
 NRV-:class:`.cost_function` handling.
 """
+
 import numpy as np
-from ..backend.NRV_Class import NRV_class, load_any
-from ..backend.NRV_Simulable import NRV_simulable, sim_results
-from ..backend.MCore import MCH, synchronize_processes
-from ..backend.log_interface import rise_warning
+from ..backend._NRV_Class import NRV_class, load_any
+from ..backend._NRV_Simulable import NRV_simulable, sim_results
+from ..backend._MCore import MCH, synchronize_processes
+from ..backend._log_interface import rise_warning
 
 
 class cost_function(NRV_class):
@@ -26,7 +27,7 @@ class cost_function(NRV_class):
         function calculating a cost from a axon simulation results, parameters:
             >>> cost_evaluation(results: sim_results, **kwargs) -> float:
     simulation  : funct
-        optional 
+        optional
     kwargs_CM           : dict
         key word arguments of context_modifier function, by default {}
     kwargs_S           : dict
@@ -88,13 +89,12 @@ def __init__(
         self.__check_mch()
         self.__synchronise_t_sim()
 
-
     ####################################
     ###### automating methods ##########
     ####################################
     def __clear_results(self):
         """
-            clear result for re-use
+        clear result for re-use
         """
         del self.simulation_context
         del self.results
@@ -103,7 +103,7 @@ def __clear_results(self):
 
     def __check_mch(self):
         """
-            check is the simulation will be handle in single or multiple cores
+        check is the simulation will be handle in single or multiple cores
         """
         if self.static_context is not None:
             static_context = load_any(self.static_context)
@@ -127,8 +127,6 @@ def __synchronise_t_sim(self):
         self.kwargs_CE["t_sim"] = self.global_t_sim
         pass
 
-
-
     @property
     def __cost_function_ok(self):
         s_status = []
@@ -138,14 +136,17 @@ def __cost_function_ok(self):
             s_status += ["context_modifier"]
         if self.cost_evaluation is None:
             s_status += ["cost_evaluation"]
-        if len(s_status)==0:
+        if len(s_status) == 0:
             return True
         else:
-            rise_warning("Cost function cannot be called because the following parameters are not defined: ",s_status)
+            rise_warning(
+                "Cost function cannot be called because the following parameters are not defined: ",
+                s_status,
+            )
             return False
 
     ## Setters
-    def set_static_context(self, static_context:str|dict, **kwgs):
+    def set_static_context(self, static_context: str | dict, **kwgs):
         """
         set the cost static_context after the instantiation
 
@@ -161,7 +162,7 @@ def set_static_context(self, static_context:str|dict, **kwgs):
         self.__check_mch()
         self.__synchronise_t_sim()
 
-    def set_context_modifier(self, context_modifier:callable, **kwgs):
+    def set_context_modifier(self, context_modifier: callable, **kwgs):
         """
         set the cost context modifier after the instantiation
 
@@ -175,7 +176,7 @@ def set_context_modifier(self, context_modifier:callable, **kwgs):
         self.kwargs_CM = kwgs
         self.__synchronise_t_sim()
 
-    def set_cost_evaluation(self, cost_evaluation:callable, **kwgs):
+    def set_cost_evaluation(self, cost_evaluation: callable, **kwgs):
         """
         set the cost evalutation function after the instantiation
 
@@ -189,9 +190,8 @@ def set_cost_evaluation(self, cost_evaluation:callable, **kwgs):
         self.kwargs_CE = kwgs
         self.__synchronise_t_sim()
 
-
     def simulate_context(self):
-        ## See what's the use of simulation 
+        ## See what's the use of simulation
         if callable(self.simulation):
             results = self.simulation(self.simulation_context, **self.kwargs_S)
         if self.simulation is None:
@@ -201,14 +201,12 @@ def simulate_context(self):
             if "save_results" not in self.kwargs_S:
                 self.kwargs_S["save_results"] = False
             results = self.simulation_context(**self.kwargs_S)
-        return results    
-
-
+        return results
 
     #############################
     ###### Call method ##########
     #############################
-    def get_sim_results(self, X:np.ndarray)->sim_results:
+    def get_sim_results(self, X: np.ndarray) -> sim_results:
         """
         Simulated the static context modified with the tuning paramters X
 
@@ -242,9 +240,7 @@ def get_sim_results(self, X:np.ndarray)->sim_results:
         self.__clear_results()
         return results
 
-
-
-    def __call__(self, X:np.ndarray)->float:
+    def __call__(self, X: np.ndarray) -> float:
         """
         When called cost function evaluate the impact of tuning
         parameters X on static context and evaluate a cost from the simulation results using
diff --git a/nrv/optim/Optimizers.py b/nrv/optim/_Optimizers.py
similarity index 95%
rename from nrv/optim/Optimizers.py
rename to nrv/optim/_Optimizers.py
index 37c4648b..dd11e90e 100644
--- a/nrv/optim/Optimizers.py
+++ b/nrv/optim/_Optimizers.py
@@ -1,6 +1,7 @@
 """
 NRV-:class:`.Optimizer` handling.
 """
+
 from abc import ABCMeta, abstractmethod
 import os
 from typing import Any
@@ -16,13 +17,13 @@
 import scipy.optimize as scpopt
 
 
-from ..backend.NRV_Class import NRV_class
-from ..backend.parameters import parameters
-from ..backend.log_interface import set_log_level, rise_error, rise_warning
-from ..backend.MCore import MCH
-from .optim_utils.optim_results import optim_results
+from ..backend._NRV_Class import NRV_class
+from ..backend._parameters import parameters
+from ..backend._log_interface import set_log_level, rise_error, rise_warning
+from ..backend._MCore import MCH
+from .optim_utils._OptimResults import optim_results
 
-dir_path = os.environ["NRVPATH"] + "/_misc"
+dir_path = parameters.nrv_path + "/_misc"
 dir_path + "/log/NRV.log"
 # mymodule.py
 
@@ -34,7 +35,7 @@ def __init__(self, method=None):
         self._method = method
         self.swarm_optimizer = False
 
-    def minimize(self, f:callable, **kwargs)->optim_results:
+    def minimize(self, f: callable, **kwargs) -> optim_results:
         """
         Minimze the function ``f`` using the `optimzer`'s parameters
 
@@ -56,14 +57,13 @@ def minimize(self, f:callable, **kwargs)->optim_results:
         results["status"] = "Processing"
         return results
 
-    def __call__(self, f:callable, **kwargs: Any) -> optim_results:
+    def __call__(self, f: callable, **kwargs: Any) -> optim_results:
         return self.minimize(f, **kwargs)
 
 
 class scipy_optimizer(Optimizer):
-
     """
-    
+
 
     Parameters
     ----------
@@ -138,22 +138,23 @@ class scipy_optimizer(Optimizer):
 
     [2] `scipy.optimize.minimize <https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html#scipy.optimize.minimize>`_
     """
+
     def __init__(
         self,
-        method:str=None,
-        x0:np.ndarray=None,
-        args:tuple=(),
-        jac:callable=None,
-        hess:callable=None,
-        hessp:callable=None,
-        bounds:tuple=None,
-        constraints:dict=(),
-        tol:float=None,
-        callback:callable=None,
-        maxiter:int=None,
-        options:dict=None,
-        dimension:int=None,
-        normalize:bool=False,
+        method: str = None,
+        x0: np.ndarray = None,
+        args: tuple = (),
+        jac: callable = None,
+        hess: callable = None,
+        hessp: callable = None,
+        bounds: tuple = None,
+        constraints: dict = (),
+        tol: float = None,
+        callback: callable = None,
+        maxiter: int = None,
+        options: dict = None,
+        dimension: int = None,
+        normalize: bool = False,
     ):
         if method is None:
             super().__init__("scipy_default")
@@ -218,7 +219,7 @@ def __normalize_bound(self, results):
         results["scale_homothety"] = self.scale_homothety
         results["scaled_bounds"] = self.scaled_bounds
 
-    def minimize(self, f:callable, **kwargs)->optim_results:
+    def minimize(self, f: callable, **kwargs) -> optim_results:
         results = super().minimize(f, **kwargs)
         if self.maxiter is not None:
             self.options["maxiter"] = self.maxiter
@@ -339,6 +340,7 @@ class PSO_optimizer(Optimizer):
 
         [2] `Pyswams handlers <https://pyswarms.readthedocs.io/en/latest/api/pyswarms.handlers.html>`_
     """
+
     def __init__(
         self,
         n_particles=5,
@@ -421,7 +423,7 @@ def __mproc_handling(self):
                 print("Terminated")
                 return False
 
-    def minimize(self, f_swarm:callable, **kwargs)-> optim_results:
+    def minimize(self, f_swarm: callable, **kwargs) -> optim_results:
         """
         Perform a Particle swarm optimization
 
diff --git a/nrv/optim/Problems.py b/nrv/optim/_Problems.py
similarity index 93%
rename from nrv/optim/Problems.py
rename to nrv/optim/_Problems.py
index 1a228098..203c6a1e 100644
--- a/nrv/optim/Problems.py
+++ b/nrv/optim/_Problems.py
@@ -1,16 +1,17 @@
 """
 NRV-:class:`.Problem` handling.
 """
+
 import numpy as np
 import faulthandler
 import traceback
 
-from ..backend.NRV_Class import NRV_class
-from ..backend.MCore import MCH, synchronize_processes
-from ..backend.log_interface import rise_error, pass_debug_info, set_log_level
-from .optim_utils.optim_results import optim_results
-from .CostFunctions import cost_function
-from .Optimizers import Optimizer
+from ..backend._NRV_Class import NRV_class
+from ..backend._MCore import MCH, synchronize_processes
+from ..backend._log_interface import rise_error, pass_debug_info, set_log_level
+from .optim_utils._OptimResults import optim_results
+from ._CostFunctions import cost_function
+from ._Optimizers import Optimizer
 
 import sys
 
@@ -120,7 +121,7 @@ def optmizer(self):
         pass
 
     # Call method is where the magic happens
-    def __call__(self, **kwargs)->optim_results:
+    def __call__(self, **kwargs) -> optim_results:
         """
         Perform the optimization: minimze the `cost_function` using `optmizer`
 
@@ -168,7 +169,7 @@ def __call__(self, **kwargs)->optim_results:
                 results.save(save=True, fname=self.problem_fname)
             return results
         else:
-            return optim_results({"dummy_res":1})
+            return optim_results({"dummy_res": 1})
 
     # Mcore handling
     def __check_MCore_CostFunction(self):
diff --git a/nrv/optim/__init__.py b/nrv/optim/__init__.py
index 1730a722..ad5dcb20 100644
--- a/nrv/optim/__init__.py
+++ b/nrv/optim/__init__.py
@@ -1,2 +1,65 @@
-""" NeuRon Virtualizer, large scale modeling of Peripheral Nervous System with random stimulation waveforms"""
-""" Optim librairy"""
+""" OPTIMIZATION methods - optim: automated optimization of any simulation parameter
+
+optim has been designed to enable optimization or automated space search of
+parameters. Any simulation can be considered as a context for optimization.
+NRV has to simple descriptors for optimization of geometrical quantities as
+well as stimulation waveforms. However, there is no formal restriction and
+specific search space can be described by the used (even electrophysiological
+quantities or morphology).
+
+The  The optimization problem, defined in a ``Problem``-class, couples a
+``Cost_Function``-object, which evaluates the cost of the problem based on
+user-specified outcomes, to an optimization method or algorithm embedded in
+a ``Optimizer``-object (see below for access to class description).
+
+The Cost_Function-class is constructed around 389 four main objects:
+
+* a filter: which is an optional Python ``callable``-object, for vector
+  formatting or space restriction of the optimization space,
+* a static context: it defines the starting point of the simulation model to
+  be  optimized. It can be any of the ``nmod``-objects or more genenerally a
+  NRV ``simulable``-object,
+* a ``ContextModifier``-object: it updates the static context according to the
+  output of the optimization algorithm and the optimization space. The
+  ``ContextModifier``-object is an abstract class, and two daughter classes
+  for specific optimization problems are currently predefined: for stimulus
+  waveform or geometry optimization (see below in the class list). Novel form
+  of user-defined optimization should be described in a custom class that
+  inherits from ``ContextModifier``,
+* a CostEvaluation-class, which is a generic Python callable-class, and that
+  can also be user-defined.
+
+
+Optimization methods and algorithms implemented in NRV rely on third-party
+optimization libraries:
+
+* SciPy optimize, that should be prefered for continuous problems,
+* Pyswarms for Particle Swarms Optimization metaheuristic in
+  high-dimensional or discontinuous cases.
+
+
+"""
+
+from ._CostFunctions import cost_function
+from ._Optimizers import Optimizer, scipy_optimizer, PSO_optimizer
+from ._Problems import cost_function_swarm_from_particle, Problem
+
+submodules = ["optim_utils"]
+
+classes = [
+    "Problem",
+    "Optimizer",
+    "scipy_optimizer",
+    "PSO_optimizer",
+    "cost_function"
+]
+
+functions = [
+    "cost_function_swarm_from_particle",
+]
+
+__all__ = []
+
+__all__ += submodules
+__all__ += classes
+__all__ += functions
\ No newline at end of file
diff --git a/nrv/optim/optim_utils/ContextModifiers.py b/nrv/optim/optim_utils/_ContextModifiers.py
similarity index 87%
rename from nrv/optim/optim_utils/ContextModifiers.py
rename to nrv/optim/optim_utils/_ContextModifiers.py
index 9e102983..5750e358 100644
--- a/nrv/optim/optim_utils/ContextModifiers.py
+++ b/nrv/optim/optim_utils/_ContextModifiers.py
@@ -1,7 +1,7 @@
 import numpy as np
-from ...backend.NRV_Class import NRV_class, load_any
-from ...backend.NRV_Simulable import NRV_simulable
-from ...fmod.stimulus import stimulus
+from ...backend._NRV_Class import NRV_class, load_any
+from ...backend._NRV_Simulable import NRV_simulable
+from ...utils._stimulus import stimulus
 
 
 class context_modifier(NRV_class):
@@ -30,7 +30,9 @@ def __init__(
         self.intracel_context = intracel_context
         self.rec_context = rec_context
 
-    def __call__(self, X: np.ndarray, static_context: NRV_simulable, **kwargs) -> NRV_simulable:
+    def __call__(
+        self, X: np.ndarray, static_context: NRV_simulable, **kwargs
+    ) -> NRV_simulable:
         """
         Modify ``static_context`` tunning paramters vector ``X``.
 
@@ -89,14 +91,14 @@ class stimulus_CM(context_modifier):
 
     def __init__(
         self,
-        stim_ID:int=0,
-        interpolator:callable=None,
-        intrep_kwargs:dict={},
-        stim_gen:callable=None,
-        stim_gen_kwargs:dict={},
-        extracel_context:bool=True,
-        intracel_context:bool=False,
-        rec_context:bool=False,
+        stim_ID: int = 0,
+        interpolator: callable = None,
+        intrep_kwargs: dict = {},
+        stim_gen: callable = None,
+        stim_gen_kwargs: dict = {},
+        extracel_context: bool = True,
+        intracel_context: bool = False,
+        rec_context: bool = False,
         **kwargs,
     ):
         super().__init__(
@@ -113,7 +115,7 @@ def __init__(
             self.intrep_kwargs[key] = kwargs[key]
             self.stim_gen_kwargs[key] = kwargs[key]
 
-    def interpolate(self, X:np.ndarray)->np.ndarray:
+    def interpolate(self, X: np.ndarray) -> np.ndarray:
         """
         interpolate the input vector with the `interpolator`. If not set, the interpolated vector will be the equal to the input vector.
         Parameters
@@ -132,7 +134,7 @@ def interpolate(self, X:np.ndarray)->np.ndarray:
             X_interp = X
         return X_interp
 
-    def stimulus_generator(self, X_interp:np.ndarray) -> stimulus:
+    def stimulus_generator(self, X_interp: np.ndarray) -> stimulus:
         """
         generated from interpolated values with  `stim_gen` function. If not set, interpolated values are set for the stimulus amplitude at constant sample rate (from zero to an argument ``t_sim``)
 
@@ -163,7 +165,9 @@ def __update_t_sim(self, local_sim):
             else:
                 self.stim_gen_kwargs["t_sim"] = local_sim.t_sim
 
-    def __call__(self, X:np.ndarray, static_sim: NRV_simulable, **kwargs) -> NRV_simulable:
+    def __call__(
+        self, X: np.ndarray, static_sim: NRV_simulable, **kwargs
+    ) -> NRV_simulable:
         """
         Modify ``static_context`` tunning paramters vector ``X``.
 
@@ -235,20 +239,21 @@ class biphasic_stimulus_CM(stimulus_CM):
     :doc:`tutorials 5</tutorials/5_first_optimization>`: First optimization problem using NRV
 
     """
+
     def __init__(
         self,
-        stim_ID:int=0,
-        start:float=1,
-        s_cathod:float|str=100,
-        t_cathod:float|str=60e-3,
-        t_inter:float|str=40e-3,
-        s_anod:float|str=None,
-        s_ratio:float|str=0.2,
-        stim_gen:callable=None,
-        stim_gen_kwargs:dict={},
-        extracel_context:bool=True,
-        intracel_context:bool=False,
-        rec_context:bool=False,
+        stim_ID: int = 0,
+        start: float = 1,
+        s_cathod: float | str = 100,
+        t_cathod: float | str = 60e-3,
+        t_inter: float | str = 40e-3,
+        s_anod: float | str = None,
+        s_ratio: float | str = 0.2,
+        stim_gen: callable = None,
+        stim_gen_kwargs: dict = {},
+        extracel_context: bool = True,
+        intracel_context: bool = False,
+        rec_context: bool = False,
     ):
         super().__init__(
             stim_ID=stim_ID,
@@ -265,7 +270,7 @@ def __init__(
         self.s_anod = s_anod
         self.s_ratio = s_ratio
 
-    def __set_values(self, X:np.ndarray):
+    def __set_values(self, X: np.ndarray):
         start = self.start
         s_cathod = self.s_cathod
         t_cathod = self.t_cathod
@@ -326,18 +331,19 @@ class harmonic_stimulus_CM(stimulus_CM):
     rec_context             : bool
         specifies whether to load rec_context with the static context
     """
+
     def __init__(
         self,
-        stim_ID:int=0,
-        start:float=1,
-        amplitude:float=100,
-        t_pulse:float=60e-3,
-        dt:float=0,
-        stim_gen:callable=None,
-        stim_gen_kwargs:dict={},
-        extracel_context:bool=True,
-        intracel_context:bool=False,
-        rec_context:bool=False,
+        stim_ID: int = 0,
+        start: float = 1,
+        amplitude: float = 100,
+        t_pulse: float = 60e-3,
+        dt: float = 0,
+        stim_gen: callable = None,
+        stim_gen_kwargs: dict = {},
+        extracel_context: bool = True,
+        intracel_context: bool = False,
+        rec_context: bool = False,
     ):
         super().__init__(
             stim_ID=stim_ID,
@@ -376,16 +382,16 @@ def stimulus_generator(self, X_interp) -> stimulus:
 class harmonic_stimulus_with_pw_CM(stimulus_CM):
     def __init__(
         self,
-        stim_ID:int=0,
-        start:float=1,
-        amplitude:float=100,
-        t_pulse:float=60e-3,
-        dt:float=0,
-        stim_gen:callable=None,
-        stim_gen_kwargs:dict={},
-        extracel_context:bool=True,
-        intracel_context:bool=False,
-        rec_context:bool=False,
+        stim_ID: int = 0,
+        start: float = 1,
+        amplitude: float = 100,
+        t_pulse: float = 60e-3,
+        dt: float = 0,
+        stim_gen: callable = None,
+        stim_gen_kwargs: dict = {},
+        extracel_context: bool = True,
+        intracel_context: bool = False,
+        rec_context: bool = False,
     ):
         super().__init__(
             stim_ID=stim_ID,
diff --git a/nrv/optim/optim_utils/CostEvaluation.py b/nrv/optim/optim_utils/_CostEvaluation.py
similarity index 87%
rename from nrv/optim/optim_utils/CostEvaluation.py
rename to nrv/optim/optim_utils/_CostEvaluation.py
index c6da4504..09d97113 100644
--- a/nrv/optim/optim_utils/CostEvaluation.py
+++ b/nrv/optim/optim_utils/_CostEvaluation.py
@@ -1,15 +1,15 @@
 import numpy as np
 
-from ...fmod.stimulus import stimulus, set_common_time_series
-from ...fmod.extracellular import extracellular_context
+from ...utils._stimulus import stimulus, set_common_time_series
+from ...fmod._extracellular import extracellular_context
 
-from ...backend.NRV_Class import NRV_class, load_any, abstractmethod
-from ...backend.NRV_Simulable import sim_results
-from ...nmod.results.axons_results import axon_results
-from ...nmod.results.fascicles_results import fascicle_results
-from ...nmod.results.nerve_results import nerve_results
-from ...utils.nrv_function import cost_evaluation
-from ...utils.cell.CL_postprocessing import *
+from ...backend._NRV_Class import NRV_class, load_any, abstractmethod
+from ...backend._NRV_Simulable import sim_results
+from ...nmod.results._axons_results import axon_results
+from ...nmod.results._fascicles_results import fascicle_results
+from ...nmod.results._nerve_results import nerve_results
+from ...utils._nrv_function import cost_evaluation
+from ...ui._axon_postprocessing import *
 
 
 class raster_count_CE(cost_evaluation):
@@ -17,6 +17,7 @@ class raster_count_CE(cost_evaluation):
     Create a callable object which returne the number of spike from the result
     of a simulation
     """
+
     def __init__(self):
         super().__init__()
 
@@ -95,13 +96,12 @@ def call_method(self, results: sim_results, **kwargs) -> float:
         if isinstance(results, axon_results):
             cost = self.count_axon_activation(results)
         else:
-            cost = results.get_recruited_axons(ax_type= 'all', normalize=False)
+            cost = results.get_recruited_axons(ax_type="all", normalize=False)
             if self.reverse:
                 cost = results.n_ax - cost
         return cost
 
 
-
 class charge_quantity_CE(cost_evaluation):
     r"""
     Create a callable object which return a value proportionnal to the charge quantity injected by stimulus.
@@ -112,6 +112,7 @@ class charge_quantity_CE(cost_evaluation):
 
     with :math:`t_k` is the discrete time step of the simulation
     """
+
     def __init__(self, id_elec=None, dt_res=0.0001):
         super().__init__()
         self.id_elec = id_elec
@@ -151,11 +152,12 @@ class stim_energy_CE(cost_evaluation):
     Parameters
     ----------
     id_elec : None | int | list[int]
-        id or list id of the electrode of the to from which the energy should be computed. If None, 
+        id or list id of the electrode of the to from which the energy should be computed. If None,
     dt_res  : float
         resolotion time step use to compute the cost value
     """
-    def __init__(self, id_elec:None|int|list[int]=None, dt_res:float=0.0001):
+
+    def __init__(self, id_elec: None | int | list[int] = None, dt_res: float = 0.0001):
         super().__init__()
         self.id_elec = id_elec
         self.dt_res = dt_res
@@ -180,4 +182,3 @@ def call_method(self, results: sim_results, **kwargs) -> float:
         for i in self.id_elec:
             cost += self.compute_stimulus_cost(extra_stim.stimuli[i])
         return cost
-
diff --git a/nrv/optim/optim_utils/OptimFunctions.py b/nrv/optim/optim_utils/_OptimFunctions.py
similarity index 90%
rename from nrv/optim/optim_utils/OptimFunctions.py
rename to nrv/optim/optim_utils/_OptimFunctions.py
index fa141b3d..c8e3108e 100644
--- a/nrv/optim/optim_utils/OptimFunctions.py
+++ b/nrv/optim/optim_utils/_OptimFunctions.py
@@ -2,9 +2,9 @@
 import matplotlib.pyplot as plt
 import csv
 
-from ...backend.file_handler import rmv_ext
-from ...backend.log_interface import rise_warning
-from ...utils.nrv_function import nrv_interp
+from ...backend._file_handler import rmv_ext
+from ...backend._log_interface import rise_warning
+from ...utils._nrv_function import nrv_interp
 
 
 ####################################################################
@@ -14,8 +14,8 @@
 
 ## interpolation
 def interpolate(
-    y:np.ndarray,
-    x:np.ndarray=[],
+    y: np.ndarray,
+    x: np.ndarray = [],
     scale=4,
     intertype="Spline",
     bounds=(0, 0),
@@ -95,16 +95,16 @@ def interpolate(
 
 
 def interpolate_amp(
-    position:np.ndarray,
-    t_sim:float=100,
-    t_end:float=None,
-    dt:float=0.005,
-    intertype:str="Spline",
-    bounds:tuple[float]=(0, 0),
-    save:bool=False,
-    filename:str="interpolate_part.dat",
-    save_scale:bool=False,
-)->np.ndarray:
+    position: np.ndarray,
+    t_sim: float = 100,
+    t_end: float = None,
+    dt: float = 0.005,
+    intertype: str = "Spline",
+    bounds: tuple[float] = (0, 0),
+    save: bool = False,
+    filename: str = "interpolate_part.dat",
+    save_scale: bool = False,
+) -> np.ndarray:
     """
     genarte a waveform from a particle position using interpolate where the position values are the output waveform amplitudes at constant sample rate
 
@@ -119,7 +119,7 @@ def interpolate_amp(
     intertype   : str
         type of interpolation perform, by default 'Spline'
         type possibly:
-            
+
             - 'Spline'                : Cubic spline interpolation
     bounds      : tupple
         limit range of the interpolation, if both equal no limit,by default (0,0)
@@ -162,22 +162,22 @@ def interpolate_amp(
 
 def interpolate_Npts(
     position,
-    t_sim:float=100,
-    dt:float=0.005,
-    amp_start:float=0,
-    amp_stop:float=1,
-    intertype:str="Spline",
-    bounds:tuple[float]=(0, 0),
-    fixed_order:bool=False,
-    t_end:float=None,
-    t_shift:float=None,
-    save:bool=False,
-    fname:str="interpolate_2pts.dat",
-    plot:bool=False,
-    save_scale:bool=False,
-    generatefigure:bool=True,
-    strict_bounds:bool=True,
-    kwargs_interp:dict={},
+    t_sim: float = 100,
+    dt: float = 0.005,
+    amp_start: float = 0,
+    amp_stop: float = 1,
+    intertype: str = "Spline",
+    bounds: tuple[float] = (0, 0),
+    fixed_order: bool = False,
+    t_end: float = None,
+    t_shift: float = None,
+    save: bool = False,
+    fname: str = "interpolate_2pts.dat",
+    plot: bool = False,
+    save_scale: bool = False,
+    generatefigure: bool = True,
+    strict_bounds: bool = True,
+    kwargs_interp: dict = {},
     **kwargs
 ):
     r"""
@@ -225,7 +225,7 @@ def interpolate_Npts(
     strict_bounds    :bool
         if True values out of bound will be set to closer bound
     kwargs_interp   : dict
-        kwargs to add to the interpollation 
+        kwargs to add to the interpollation
 
     Returns
     -------
diff --git a/nrv/optim/optim_utils/optim_results.py b/nrv/optim/optim_utils/_OptimResults.py
similarity index 89%
rename from nrv/optim/optim_utils/optim_results.py
rename to nrv/optim/optim_utils/_OptimResults.py
index 2d89c3d4..83a4df4b 100644
--- a/nrv/optim/optim_utils/optim_results.py
+++ b/nrv/optim/optim_utils/_OptimResults.py
@@ -1,12 +1,12 @@
 import matplotlib.pyplot as plt
 from matplotlib.animation import FuncAnimation, PillowWriter, FFMpegWriter
-from .OptimFunctions import interpolate_Npts
-from ..CostFunctions import cost_function
+from ._OptimFunctions import interpolate_Npts
+from .._CostFunctions import cost_function
 import numpy as np
 
-from ...backend.NRV_Results import NRV_results
-from ...backend.MCore import MCH
-from ...backend.log_interface import pass_info, rise_warning
+from ...backend._NRV_Results import NRV_results
+from ...backend._MCore import MCH
+from ...backend._log_interface import pass_info, rise_warning
 
 
 class optim_results(NRV_results):
@@ -95,7 +95,7 @@ def findbestpart(self, decimals=10, verbose=False, lim_it=None):
             pass_info("not found with decimals =", decimals)
         return self.findbestpart(decimals - 1, verbose=verbose, lim_it=lim_it)
 
-    def compute_best_pos(self, cost_function:cost_function, **kwrgs):
+    def compute_best_pos(self, cost_function: cost_function, **kwrgs):
         if MCH.is_alone():
             return cost_function.get_sim_results(self.x)
         else:
@@ -110,7 +110,12 @@ def compute_best_pos(self, cost_function:cost_function, **kwrgs):
     ##    plotting methods    ##
     ############################
     def plot_cost_history(
-        self, ax:plt.axes, nitstop:int=-1, xlog:bool=False, ylog:bool=False,**ax_kwargs
+        self,
+        ax: plt.axes,
+        nitstop: int = -1,
+        xlog: bool = False,
+        ylog: bool = False,
+        **ax_kwargs
     ):
         cost = self["cost_history"]
         ax.plot(cost[0:nitstop], **ax_kwargs)
diff --git a/nrv/optim/optim_utils/__init__.py b/nrv/optim/optim_utils/__init__.py
index c06e9141..329d4075 100644
--- a/nrv/optim/optim_utils/__init__.py
+++ b/nrv/optim/optim_utils/__init__.py
@@ -1,2 +1,51 @@
-""" NeuRon Virtualizer, large scale modeling of Peripheral Nervous System with random stimulation waveforms"""
-""" optim utils submodule"""
+""" NeuRon Virtualizer, large scale modeling of Peripheral Nervous System with random stimulation waveforms
+optim utils submodule"""
+
+from ._ContextModifiers import (
+    context_modifier,
+    stimulus_CM,
+    biphasic_stimulus_CM,
+    harmonic_stimulus_CM,
+    harmonic_stimulus_with_pw_CM,
+)
+from ._CostEvaluation import (
+    raster_count_CE,
+    recrutement_count_CE,
+    charge_quantity_CE,
+    stim_energy_CE,
+)
+from ._OptimResults import optim_results
+from ._OptimFunctions import (
+    interpolate,
+    interpolate_amp,
+    interpolate_Npts,
+    cost_position_saver,
+)
+
+submodules = []
+
+classes = [
+    "context_modifier",
+    "stimulus_CM",
+    "biphasic_stimulus_CM",
+    "harmonic_stimulus_CM",
+    "harmonic_stimulus_with_pw_CM",
+    "raster_count_CE",
+    "recrutement_count_CE",
+    "charge_quantity_CE",
+    "stim_energy_CE",
+    "optim_results",
+]
+
+functions = [
+    "interpolate",
+    "interpolate_amp",
+    "interpolate_Npts",
+    "cost_position_saver",
+]
+
+__all__ = []
+
+__all__ += submodules
+__all__ += classes
+__all__ += functions
diff --git a/nrv/ui/_NRV_Msh.py b/nrv/ui/_NRV_Msh.py
new file mode 100644
index 00000000..b4550ae0
--- /dev/null
+++ b/nrv/ui/_NRV_Msh.py
@@ -0,0 +1,177 @@
+from ..backend._log_interface import rise_warning
+from ..nmod._nerve import nerve
+from ..nmod._fascicles import fascicle
+from ..utils._units import *
+from ..fmod._electrodes import *
+from ..fmod._extracellular import is_FEM_extra_stim, FEM_stimulation
+from ..fmod.FEM.mesh_creator._NerveMshCreator import *
+
+
+def mesh_from_electrode(
+    elec: FEM_electrode,
+    mesh: NerveMshCreator = None,
+    Length: float = 10000,
+    Outer_D: float = 5,
+    Nerve_D: float = 4000,
+    y_c: float = 0,
+    z_c: float = 0,
+    res: float | str = "default",
+) -> NerveMshCreator:
+    """
+    returns the corresponding mesh from a nrv.facsicle
+    """
+    elec = load_any(elec)
+    if not is_FEM_electrode(elec):
+        rise_warning("Only FEM electrode can be added to a mesh")
+    else:
+        if mesh is None:
+            mesh = NerveMshCreator(
+                Length=Length, Outer_D=Outer_D, Nerve_D=Nerve_D, y_c=y_c, z_c=z_c
+            )
+        elec.parameter_model(mesh, res=res)
+    return mesh
+
+
+def mesh_from_extracellular_context(
+    extracel_context: FEM_stimulation,
+    mesh: NerveMshCreator | None = None,
+    Length: float = 10000,
+    Outer_D: float = 5,
+    Nerve_D: float = 4000,
+    y_c: float = 0,
+    z_c: float = 0,
+    res_elec: list[float] | float | str = "default",
+) -> NerveMshCreator:
+    """
+    returns the corresponding mesh from a nrv.facsicle
+    """
+    extracel_context = load_any(extracel_context)
+    if not is_FEM_extra_stim(extracel_context):
+        rise_warning("Only FEM electrode can be added to a mesh")
+    else:
+        N_contact = 0
+        if np.iterable(res_elec) and not isinstance(res_elec, str):
+            if len(res_elec) == len(fascicle.extra_stim.electrodes):
+                res = res_elec
+            else:
+                rise_warning(
+                    "length of res_elec and fascicle.extra_stim.electrodes does not match",
+                    "only first value kept",
+                )
+                res = [res_elec[0] for k in range(len(fascicle.extra_stim.electrodes))]
+        else:
+            res = [res_elec for k in range(len(fascicle.extra_stim.electrodes))]
+        if mesh is None:
+            mesh = NerveMshCreator(
+                Length=Length, Outer_D=Outer_D, Nerve_D=Nerve_D, y_c=y_c, z_c=z_c
+            )
+        for i_elec, elec in enumerate(extracel_context.electrodes):
+            if (not elec.is_multipolar) or N_contact <= 0:
+                mesh = mesh_from_electrode(elec, mesh=mesh, res=res[i_elec])
+                if elec.is_multipolar:
+                    N_contact = elec.N_contact
+            else:
+                N_contact -= 1
+    return mesh
+
+
+def mesh_from_fascicle(
+    fascicle: fascicle,
+    mesh: NerveMshCreator | None = None,
+    Length: float = 10000,
+    Outer_D: float = 5,
+    Nerve_D: float = 4000,
+    y_c: float = 0,
+    z_c: float = 0,
+    add_axons: bool = True,
+    add_context: bool = False,
+    res_nerve: float | str = "default",
+    res_fasc: float | str = "default",
+    res_ax: list[float] | float | str = "default",
+    res_elec: list[float] | float | str = "default",
+) -> NerveMshCreator:
+    """
+    returns the corresponding mesh from a nrv.facsicle
+    """
+    fascicle = load_any(fascicle, extracel_context=True)
+    if mesh is None:
+        mesh = NerveMshCreator(
+            Length=Length, Outer_D=Outer_D, Nerve_D=Nerve_D, y_c=y_c, z_c=z_c
+        )
+        if res_nerve != "default":
+            mesh.reshape_nerve(res=res_nerve)
+
+    mesh.reshape_fascicle(
+        d=fascicle.D,
+        y_c=fascicle.y_grav_center,
+        z_c=fascicle.z_grav_center,
+        res=res_fasc,
+    )
+    if add_axons:
+        is_NoR_relative_position = len(fascicle.NoR_relative_position) != 0
+        for i_ax in range(fascicle.n_ax):
+            if is_NoR_relative_position:
+                node_sift = fascicle.NoR_relative_position[i_ax]
+            else:
+                node_sift = 0
+            ax_d = round(fascicle.axons_diameter[i_ax], 3)
+            ax_y = round(fascicle.axons_y[i_ax], 3)
+            ax_z = round(fascicle.axons_z[i_ax], 3)
+            mye = bool(fascicle.axons_type[i_ax])
+            if isinstance(res_ax, str) and res_ax != "default":
+                res_ax = eval(str(fascicle.axons_diameter[i_ax]) + res_ax)
+            mesh.reshape_axon(
+                d=ax_d, y=ax_y, z=ax_z, myelinated=mye, node_sift=node_sift, res=res_ax
+            )
+    if add_context and fascicle.extra_stim is not None:
+        mesh = mesh_from_extracellular_context(
+            fascicle.extra_stim, mesh=mesh, res_elec=res_elec
+        )
+    return mesh
+
+
+def mesh_from_nerve(
+    nerve: nerve,
+    length: float = None,
+    add_axons: bool = True,
+    res_nerve: float | str = "default",
+    res_fasc: list[float] | float | str = "default",
+    res_ax: list[float] | float | str = "default",
+    res_elec: list[float] | float | str = "default",
+) -> NerveMshCreator:
+    """ """
+    nerve = load_any(nerve, extracel_context=True)
+    length = length or nerve.L
+    mesh = NerveMshCreator(
+        Length=length,
+        Outer_D=nerve.Outer_D,
+        Nerve_D=nerve.D,
+        y_c=nerve.y_grav_center,
+        z_c=nerve.z_grav_center,
+    )
+    mesh.reshape_nerve(res=res_nerve)
+    if np.iterable(res_fasc) and not isinstance(res_fasc, str):
+        if len(res_fasc) == len(nerve.fascicles):
+            res = res_fasc
+        else:
+            rise_warning(
+                "length of res_fasc and nerve.fascicles does not match",
+                "only first value kept",
+            )
+            res = [res_fasc[0] for k in range(len(nerve.fascicles))]
+    else:
+        res = [res_fasc for k in range(len(nerve.fascicles))]
+    for i_fasc, fasc in enumerate(nerve.fascicles.values()):
+        mesh = mesh_from_fascicle(
+            fasc,
+            mesh=mesh,
+            add_context=False,
+            add_axons=add_axons,
+            res_ax=res_ax,
+            res_fasc=res[i_fasc],
+        )
+    if "extra_stim" in nerve.__dict__ and nerve.extra_stim is not None:
+        mesh = mesh_from_extracellular_context(
+            nerve.extra_stim, mesh=mesh, res_elec=res_elec
+        )
+    return mesh
diff --git a/nrv/ui/__init__.py b/nrv/ui/__init__.py
new file mode 100644
index 00000000..22ee46d0
--- /dev/null
+++ b/nrv/ui/__init__.py
@@ -0,0 +1,127 @@
+""" User Interface - ui: end user pre- or post processing code
+
+ui provides classes and functions for pre- (meshing for instance) or
+post-processing computations. Basic or recurent simulation encapuslated
+as function are also accessible.
+
+"""
+
+
+from ._axon_simulations import (
+    search_threshold_dispatcher,
+    axon_AP_threshold,
+    axon_block_threshold,
+    firing_threshold_point_source,
+    firing_threshold_from_axon,
+    para_firing_threshold,
+    blocking_threshold_point_source,
+    blocking_threshold_from_axon,
+    para_blocking_threshold,
+)
+
+from ._axon_postprocessing import (
+    remove_key,
+    remove_non_NoR_zones,
+    generate_axon_from_results,
+    filter_freq,
+    rasterize,
+    AP_detection,
+    speed,
+    block,
+    max_spike_position,
+    count_spike,
+    check_test_AP,
+    detect_start_extrastim,
+    extra_stim_properties,
+    axon_state,
+    get_index_myelinated_sequence,
+    find_central_node_index,
+    compute_f_mem,
+    get_myelin_properties,
+    plot_Nav_states,
+    default_PP,
+    rmv_keys,
+    is_recruited,
+    is_blocked,
+    sample_g_mem,
+    vmem_plot,
+    raster_plot,
+)
+
+from ._fascicle_postprocessing import(
+    ls_axons_results,
+    ls_csv,
+    rm_file,
+    rm_sim_dir,
+    rm_sim_dir_from_results,
+    CAP_time_detection,
+    fascicular_state,
+    plot_fasc_state,
+)
+
+from ._NRV_Msh import (
+    mesh_from_electrode,
+    mesh_from_extracellular_context,
+    mesh_from_fascicle,
+    mesh_from_nerve,
+)
+
+submodules = []
+
+classes = []
+
+functions = [
+    "search_threshold_dispatcher",
+    "axon_AP_threshold",
+    "axon_block_threshold",
+    "firing_threshold_point_source",
+    "firing_threshold_from_axon",
+    "para_firing_threshold",
+    "blocking_threshold_point_source",
+    "blocking_threshold_from_axon",
+    "para_blocking_threshold",
+    "remove_key",
+    "remove_non_NoR_zones",
+    "generate_axon_from_results",
+    "filter_freq",
+    "rasterize",
+    "AP_detection",
+    "speed",
+    "block",
+    "max_spike_position",
+    "count_spike",
+    "check_test_AP",
+    "detect_start_extrastim",
+    "extra_stim_properties",
+    "axon_state",
+    "get_index_myelinated_sequence",
+    "find_central_node_index",
+    "compute_f_mem",
+    "get_myelin_properties",
+    "plot_Nav_states",
+    "default_PP",
+    "rmv_keys",
+    "is_recruited",
+    "is_blocked",
+    "sample_g_mem",
+    "vmem_plot",
+    "raster_plot",
+    "ls_axons_results",
+    "ls_csv",
+    "rm_file",
+    "rm_sim_dir",
+    "rm_sim_dir_from_results",
+    "CAP_time_detection",
+    "fascicular_state",
+    "plot_fasc_state",
+    "mesh_from_electrode",
+    "mesh_from_extracellular_context",
+    "mesh_from_fascicle",
+    "mesh_from_nerve",
+]
+
+__all__ = []
+
+__all__ += submodules
+__all__ += classes
+__all__ += functions
diff --git a/nrv/utils/cell/CL_postprocessing.py b/nrv/ui/_axon_postprocessing.py
similarity index 99%
rename from nrv/utils/cell/CL_postprocessing.py
rename to nrv/ui/_axon_postprocessing.py
index ee52f750..09f3368a 100644
--- a/nrv/utils/cell/CL_postprocessing.py
+++ b/nrv/ui/_axon_postprocessing.py
@@ -13,15 +13,15 @@
 import matplotlib.pyplot as plt
 from scipy import signal
 
-from ...backend.file_handler import is_iterable, json_dump, json_load
-from ...backend.log_interface import pass_info, rise_warning, rise_error
-from ...backend.NRV_Class import load_any
-from ..units import MHz
-from ...backend.file_handler import rmv_ext
-from ..misc import distance_point2line
-from ...nmod.unmyelinated import unmyelinated
-from ...nmod.myelinated import myelinated
-from ...nmod.results.axons_results import axon_results
+from ..backend._file_handler import is_iterable, json_dump, json_load
+from ..backend._log_interface import pass_info, rise_warning, rise_error
+from ..backend._NRV_Class import load_any
+from ..backend._file_handler import rmv_ext
+from ..utils._units import MHz
+from ..utils._misc import distance_point2line
+from ..nmod._unmyelinated import unmyelinated
+from ..nmod._myelinated import myelinated
+from ..nmod.results._axons_results import axon_results
 
 
 # enable faulthandler to ease 'segmentation faults' debug
diff --git a/nrv/utils/cell/CL_simulations.py b/nrv/ui/_axon_simulations.py
similarity index 93%
rename from nrv/utils/cell/CL_simulations.py
rename to nrv/ui/_axon_simulations.py
index 0f742f61..721f466b 100644
--- a/nrv/utils/cell/CL_simulations.py
+++ b/nrv/ui/_axon_simulations.py
@@ -6,18 +6,22 @@
 from time import perf_counter
 from multiprocessing import Pool
 from tqdm import tqdm
-
-from ...backend.log_interface import pass_info, rise_error, rise_warning, clear_prompt_line
-from ...backend.MCore import *
-from ...fmod.electrodes import *
-from ...fmod.extracellular import *
-from ...fmod.materials import *
-from ...fmod.stimulus import *
-from ...nmod.axons import *
-from ...nmod.myelinated import *
-from ...nmod.unmyelinated import *
-from ..saving_handler import *
-from .CL_postprocessing import *
+from functools import partial
+from itertools import repeat
+
+from ..backend._file_handler import is_iterable
+from ..backend._log_interface import pass_info, rise_error, rise_warning, clear_prompt_line
+from ..backend._parameters import parameters
+from ..backend._MCore import *
+from ..fmod._electrodes import *
+from ..fmod._extracellular import *
+from ..fmod._materials import *
+from ..nmod._axons import *
+from ..nmod._myelinated import *
+from ..nmod._unmyelinated import *
+from ..utils._stimulus import *
+from ..utils._saving_handler import *
+from ._axon_postprocessing import *
 
 unmyelinated_models = [
     "HH",
@@ -29,7 +33,11 @@
 ]
 myelinated_models = ["MRG", "Gaines_motor", "Gaines_sensory"]
 
-def search_threshold_dispatcher(search_func: Callable, parameter_list: list[any], ncore: int=None)->list[any]:
+
+def set_args_kwargs(func, args, kwargs):   
+    return func(*args, **kwargs)
+
+def search_threshold_dispatcher(search_func: Callable, parameter_list: list[any], ncore: int=None, **kwargs)->list[any]:
     """
     Automatically dispatches any search threshold callable object on available cpu cores. 
 
@@ -47,18 +55,39 @@ def search_threshold_dispatcher(search_func: Callable, parameter_list: list[any]
     list[any]
         List of ordered thresholds.
     """
-    tot = len(parameter_list)
+    
+    l_kwargs = []
+    c_kwargs = {}
+    tot = len(list(parameter_list))
     if ncore is not None:
         tot = ncore
+    for k in range(tot):
+        n_kwargs = {}
+        for key in kwargs:
+            if is_iterable(kwargs[key]):
+                if len (kwargs[key]) == tot:
+                    n_kwargs[key] = kwargs[key][k]
+                else:
+                    rise_warning(f"length of kwargs {key} in {__name__} is inconsistant. Got {len (kwargs[key])}, expected {tot}.")
+                    pass_info(f"Used {key}[0] in pool")
+                    c_kwargs[key] = kwargs[key][0]
+            else:
+                c_kwargs[key] = kwargs[key]
+            l_kwargs.append(n_kwargs)
+    
+    p_search_func = partial(search_func,**c_kwargs)
     with Pool(tot) as pool: 
-        results = list(tqdm(pool.imap(search_func, parameter_list), total=len(parameter_list)))
+        args_for_starmap = zip(repeat(p_search_func), zip(parameter_list), l_kwargs)
+        results = list(tqdm(pool.starmap(set_args_kwargs,args_for_starmap)))
         pool.close()
         pool.join()
         return(results)
 
+
+
 def axon_AP_threshold(axon: axon, amp_max: float, update_func: Callable,
-                      t_sim: float = 5, tol: float = 1,
-                      verbose: bool = True, args_update = None ,**kwargs) -> np.float64 :
+                      t_sim: float = 5, tol: float = 1, t_start = None, freq = None,
+                      verbose: bool = True, args_update = None, save_path: str|None = None, **kwargs) -> np.float64 :
     """
     Find the activation threshold of an axon with arbitrary stimulation settings.
 
@@ -78,6 +107,8 @@ def axon_AP_threshold(axon: axon, amp_max: float, update_func: Callable,
         Verbosity of the search, by default True
     args_update : arg, optional
         update_func arguments, by default None
+    save_path : str, optional
+        if not none, raster_plot and plot_x_t of axon results are saved in save_path
 
     Returns
     -------
@@ -99,6 +130,10 @@ def axon_AP_threshold(axon: axon, amp_max: float, update_func: Callable,
     amplitude_min_th = amp_min
     amplitude_tol = tol
 
+    vm_key = "V_mem"
+    if (freq is not None):
+        vm_key += "_filtered"
+
     # Dichotomy initialization
     previous_amp = amp_min
     delta_amp = np.abs(amp_max - amp_min)
@@ -112,7 +147,31 @@ def axon_AP_threshold(axon: axon, amp_max: float, update_func: Callable,
             pass_info(f"Iteration {Niter}, Amp is {np.round(current_amp,2)}µA ...")
             
         update_func(axon,current_amp,**args_update)
+        verb = parameters.get_nrv_verbosity()
+        parameters.set_nrv_verbosity(2)
         results = axon.simulate(t_sim=t_sim)
+        parameters.set_nrv_verbosity(verb)
+
+        if freq is not None:
+            results.filter_freq("V_mem", freq, Q=2)
+
+        if save_path:
+            fig, ax = plt.subplots(1)
+            results.raster_plot(ax,key = vm_key)
+            ax.set_title(f"Amplitude: {np.round(current_amp,2)}µA")
+            amp_str = str(np.round(current_amp,2)).replace(".", "_")
+            fig.tight_layout()
+            fig_name = save_path + f"raster_plot_axon_{axon.ID}_amp_{amp_str}_uA_iter_{Niter}.png"
+            fig.savefig(fig_name)
+            plt.close(fig)
+
+            fig, ax = plt.subplots(1)
+            results.plot_x_t(ax,key = vm_key)
+            ax.set_title(f"Amplitude: {np.round(current_amp,2)}µA")
+            fig.tight_layout()
+            fig_name = save_path + f"vmen_plot_axon_{axon.ID}_amp_{amp_str}_uA_iter_{Niter}.png"
+            fig.savefig(fig_name)
+            plt.close(fig)
 
         if verbose:
             clear_prompt_line(1)
@@ -136,7 +195,7 @@ def axon_AP_threshold(axon: axon, amp_max: float, update_func: Callable,
                 keep_going = 1
         previous_amp = current_amp
         # test simulation results, update dichotomy
-        if results.is_recruited("V_mem"):
+        if results.is_recruited(vm_key=vm_key,t_start=t_start):
             if current_amp == amp_min:
                 rise_warning("Minimum Stimulation Current is too High!")
                 return 0
@@ -233,14 +292,20 @@ def axon_block_threshold(axon: axon, amp_max: float, update_func: Callable, AP_s
             pass_info(f"Iteration {Niter}, Amp is {np.round(current_amp,2)}µA ...")
             
         update_func(axon,current_amp,**args_update)
+
+        verb = parameters.get_nrv_verbosity()
+        #parameters.set_nrv_verbosity(2)
         results = axon.simulate(t_sim=t_sim)
+        #parameters.set_nrv_verbosity(verb)
+
         is_blocked = results.is_blocked(AP_start=AP_start, freq=freq)
         if save_path:
             fig, ax = plt.subplots(1)
             results.raster_plot(ax,key = vm_key)
             ax.set_title(f"Block Amplitude: {np.round(current_amp,2)}µA")
+            amp_str = str(np.round(current_amp,2)).replace(".", "_")
             fig.tight_layout()
-            fig_name = save_path + f"raster_plot_axon_{axon.ID}_iter_{Niter}.png"
+            fig_name = save_path + f"raster_plot_axon_{axon.ID}_amp_{amp_str}_uA_iter_{Niter}.png"
             fig.savefig(fig_name)
             plt.close(fig)
 
@@ -248,7 +313,7 @@ def axon_block_threshold(axon: axon, amp_max: float, update_func: Callable, AP_s
             results.plot_x_t(ax,key = vm_key)
             ax.set_title(f"Block Amplitude: {np.round(current_amp,2)}µA")
             fig.tight_layout()
-            fig_name = save_path + f"vmen_plot_axon_{axon.ID}_iter_{Niter}.png"
+            fig_name = save_path + f"vmen_plot_axon_{axon.ID}_amp_{amp_str}_uA_iter_{Niter}.png"
             fig.savefig(fig_name)
             plt.close(fig)
 
@@ -305,7 +370,7 @@ def axon_block_threshold(axon: axon, amp_max: float, update_func: Callable, AP_s
     t_stop = perf_counter()
     if verbose:
         clear_prompt_line(1)
-        pass_info(f"Activation threshold is {np.round(current_amp,2)}µA ({np.round(current_tol,2)}%),"
+        pass_info(f"Block threshold is {np.round(current_amp,2)}µA ({np.round(current_tol,2)}%),"
                   + f" found in {Niter-1} iterations ({np.round(t_stop-t_start,2)}s).")
     return current_amp
 
diff --git a/nrv/utils/fascicle/FL_postprocessing.py b/nrv/ui/_fascicle_postprocessing.py
similarity index 81%
rename from nrv/utils/fascicle/FL_postprocessing.py
rename to nrv/ui/_fascicle_postprocessing.py
index dc2eca12..f575c480 100644
--- a/nrv/utils/fascicle/FL_postprocessing.py
+++ b/nrv/ui/_fascicle_postprocessing.py
@@ -1,15 +1,16 @@
 """
 NRV-Facsiclular Level postprocessing.
 """
+
 import faulthandler
 import os
 
 import matplotlib.pyplot as plt
 
-from ...backend.file_handler import json_load
-from ...backend.log_interface import pass_info
-from ...fmod.electrodes import is_FEM_electrode
-from ..cell.CL_postprocessing import *
+from ..backend._file_handler import json_load
+from ..backend._log_interface import pass_info
+from ..fmod._electrodes import is_FEM_electrode
+from ._axon_postprocessing import *
 
 # enable faulthandler to ease 'segmentation faults' debug
 faulthandler.enable()
@@ -35,13 +36,11 @@ def ls_axons_results(dir_path):
         list of axons result files
     """
 
-    rise_warning(
-        "DeprecationWarning: ",
-        "ls_axons_results is deprecated."
-    )
+    rise_warning("DeprecationWarning: ", "ls_axons_results is deprecated.")
     list_files = [file for file in os.listdir(dir_path) if file[0:9] == "sim_axon_"]
     return list_files
 
+
 def ls_csv(dir_path):
     """
     return list of axons simulation result files
@@ -56,10 +55,7 @@ def ls_csv(dir_path):
     files        :list of str
         list of axons result files
     """
-    rise_warning(
-        "DeprecationWarning: ",
-        "ls_csv is depecrated."
-    )
+    rise_warning("DeprecationWarning: ", "ls_csv is depecrated.")
     list_files = [file for file in os.listdir(dir_path) if file[-4:] == ".csv"]
     return list_files
 
@@ -75,10 +71,7 @@ def rm_file(file_path, verbose=True):
     verbose     : str
         pass information when file is deleted
     """
-    rise_warning(
-        "DeprecationWarning: ",
-        "rm_file is deprecated."
-    )
+    rise_warning("DeprecationWarning: ", "rm_file is deprecated.")
     os.remove(file_path)
     pass_info("folowing file removed :" + file_path, verbose=verbose)
 
@@ -96,10 +89,7 @@ def rm_sim_dir(dir_path, verbose=True):
         pass information when file is deleted
     """
 
-    rise_warning(
-        "DeprecationWarning: ",
-        "rm_sim_dir is deprecated."
-    )
+    rise_warning("DeprecationWarning: ", "rm_sim_dir is deprecated.")
     if os.path.exists(dir_path):
         # messaging saying folder not empty
         if os.path.exists(
@@ -107,7 +97,7 @@ def rm_sim_dir(dir_path, verbose=True):
         ):
             rm_file(dir_path + "00_Fascicle_config.json", verbose)
 
-        for file in ls_axons_results(dir_path)+ls_csv(dir_path):
+        for file in ls_axons_results(dir_path) + ls_csv(dir_path):
             rm_file(dir_path + file, verbose)
         # checking whether the folder is empty or not
         if len(os.listdir(dir_path)) == 0:
@@ -123,6 +113,7 @@ def rm_sim_dir(dir_path, verbose=True):
         # file not found message
         pass_info("Folder not found in the directory", verbose=verbose)
 
+
 def rm_sim_dir_from_results(results, verbose=True):
     """
     Delete directory
@@ -135,18 +126,17 @@ def rm_sim_dir_from_results(results, verbose=True):
     verbose     : str
         pass information when file is deleted
     """
-    rise_warning(
-        "DeprecationWarning: ",
-        "rm_sim_dir_from_results is deprecated."
-    )
-    fasc_dir = results["save_path"] + "Fascicle_" +str(results["ID"]) + "/"
+    rise_warning("DeprecationWarning: ", "rm_sim_dir_from_results is deprecated.")
+    fasc_dir = results["save_path"] + "Fascicle_" + str(results["ID"]) + "/"
     rm_sim_dir(dir_path=fasc_dir, verbose=verbose)
 
-def CAP_time_detection(Voltage, t, t_stim=0, stim_duration=0,tol=0.05, myelinated=False,\
-    index=True):
+
+def CAP_time_detection(
+    Voltage, t, t_stim=0, stim_duration=0, tol=0.05, myelinated=False, index=True
+):
     """
     internal use, Return index in the time scale or time of the start and stop of
-    a Compound Action Potentiel 
+    a Compound Action Potentiel
 
     Parameters
     ----------
@@ -164,25 +154,22 @@ def CAP_time_detection(Voltage, t, t_stim=0, stim_duration=0,tol=0.05, myelinate
         if true the time index is returned, else the time value
     """
 
-    rise_warning(
-        "DeprecationWarning: ",
-        "CAP_time_detection is deprecated."
-    )
+    rise_warning("DeprecationWarning: ", "CAP_time_detection is deprecated.")
     i_start_unm, i_stop_unm = 0, 0
     i_start_m, i_stop_m = 0, 0
     dt = t[1] - t[0]
-    offset = int((t_stim + stim_duration)/dt)+1
+    offset = int((t_stim + stim_duration) / dt) + 1
 
     S = Voltage
     N = len(S) - offset
 
-    for i in range(N-1):
-        if i_start_unm == 0 and S[i+offset]- S[-1] > tol:
-            i_start_unm = i+offset
-        if i_stop_unm == 0 and abs(S[len(S)-i-1])- abs(S[-1]) > tol:
+    for i in range(N - 1):
+        if i_start_unm == 0 and S[i + offset] - S[-1] > tol:
+            i_start_unm = i + offset
+        if i_stop_unm == 0 and abs(S[len(S) - i - 1]) - abs(S[-1]) > tol:
             i_stop_unm = len(S) - i - 1
 
-    if myelinated is False: 
+    if myelinated is False:
         i_max = i_start_unm + np.argmax(Voltage[i_start_unm:i_stop_unm])
         i_min = i_start_unm + np.argmin(Voltage[i_start_unm:i_stop_unm])
         if index:
@@ -193,15 +180,15 @@ def CAP_time_detection(Voltage, t, t_stim=0, stim_duration=0,tol=0.05, myelinate
         ## No unmyelinated CAP found
         if i_start_unm == 0:
             i_stop_m = i_stop_unm
-            for i in range(N-1):
-                if i_start_m == 0 and abs(S[i+offset])-abs(S[-1])> tol:
-                    i_start_m = i+offset
+            for i in range(N - 1):
+                if i_start_m == 0 and abs(S[i + offset]) - abs(S[-1]) > tol:
+                    i_start_m = i + offset
         else:
             N = i_start_unm - offset
-            for i in range(N-1):
-                if i_start_m == 0 and abs(S[i+offset])- abs(S[-1]) > tol:
-                    i_start_m = i+offset
-                if i_stop_m == 0 and abs(S[i_start_unm-i-1])- abs(S[-1]) > tol:
+            for i in range(N - 1):
+                if i_start_m == 0 and abs(S[i + offset]) - abs(S[-1]) > tol:
+                    i_start_m = i + offset
+                if i_stop_m == 0 and abs(S[i_start_unm - i - 1]) - abs(S[-1]) > tol:
                     i_stop_m = i_start_unm - i - 1
         i_max = np.argmax(Voltage[offset:])
         i_min = i_start_m + np.argmin(Voltage[i_start_m:i_stop_m])
@@ -211,6 +198,7 @@ def CAP_time_detection(Voltage, t, t_stim=0, stim_duration=0,tol=0.05, myelinate
         else:
             return t[i_start_m], t[i_max], t[i_min], t[i_stop_m]
 
+
 #############################
 ##### Result processing #####
 #############################
@@ -240,14 +228,14 @@ def fascicular_state(
 
     rise_warning(
         "DeprecationWarning: ",
-        "fascicular_state is deprecated, use block_summary from axon_results instead."
+        "fascicular_state is deprecated, use block_summary from axon_results instead.",
     )
 
     fascicular = json_load(dir_path + "00_Fascicle_config.json")
     facsicular_state = {"-1": fascicular}
     N_ax = len(fascicular["axons_diameter"])
     for i in range(N_ax):
-        file = "sim_axon_"+ str(i) + ".json"
+        file = "sim_axon_" + str(i) + ".json"
         if "extra_stim" not in facsicular_state["-1"]:
             facsicular_state["-1"]["extra_stim"] = extra_stim_properties(
                 dir_path + file
@@ -296,7 +284,7 @@ def plot_fasc_state(
 
     rise_warning(
         "DeprecationWarning: ",
-        "plot_fasc_state is deprecated, use plot_block_summary from fascicules_results instead."
+        "plot_fasc_state is deprecated, use plot_block_summary from fascicules_results instead.",
     )
 
     fasc = facsicular_state["-1"]
@@ -326,12 +314,15 @@ def plot_fasc_state(
     alpha = [1 - (i / (1 + max(alpha))) for i in alpha]
 
     ## plot contour
-    axes.add_patch(plt.Circle(
-                (fasc["y_grav_center"], fasc["z_grav_center"]),
-                fasc["D"]/2,
-                color=contour_color,
-                fill=False,
-                linewidth=2,))
+    axes.add_patch(
+        plt.Circle(
+            (fasc["y_grav_center"], fasc["z_grav_center"]),
+            fasc["D"] / 2,
+            color=contour_color,
+            fill=False,
+            linewidth=2,
+        )
+    )
     ## plot axons
     circles = []
     for k in range(N):
@@ -374,4 +365,4 @@ def plot_fasc_state(
                     )
                 )
             elif not is_FEM_electrode(electrode):
-                axes.scatter(electrode.y, electrode.z, color="gold")
\ No newline at end of file
+                axes.scatter(electrode.y, electrode.z, color="gold")
diff --git a/nrv/fmod/FEM/mesh_creator/NRV_Msh.py b/nrv/utils/_NRV_Msh.py
similarity index 70%
rename from nrv/fmod/FEM/mesh_creator/NRV_Msh.py
rename to nrv/utils/_NRV_Msh.py
index 62992a25..20045053 100644
--- a/nrv/fmod/FEM/mesh_creator/NRV_Msh.py
+++ b/nrv/utils/_NRV_Msh.py
@@ -1,22 +1,22 @@
-from ....backend.log_interface import rise_warning
-from ....nmod.nerve import nerve
-from ....nmod.fascicles import fascicle
-from ....utils.units import *
-from ...electrodes import *
-from ...extracellular import is_FEM_extra_stim, FEM_stimulation
-from .NerveMshCreator import *
+from ..backend._log_interface import rise_warning
+from ..nmod._nerve import nerve
+from ..nmod._fascicles import fascicle
+from ._units import *
+from ..fmod._electrodes import *
+from ..fmod._extracellular import is_FEM_extra_stim, FEM_stimulation
+from ..fmod.FEM.mesh_creator._NerveMshCreator import *
 
 
 def mesh_from_electrode(
-    elec:FEM_electrode,
-    mesh:NerveMshCreator=None,
-    Length:float=10000,
-    Outer_D:float=5,
-    Nerve_D:float=4000,
-    y_c:float=0,
-    z_c:float=0,
-    res:float | str="default",
-)->NerveMshCreator:
+    elec: FEM_electrode,
+    mesh: NerveMshCreator = None,
+    Length: float = 10000,
+    Outer_D: float = 5,
+    Nerve_D: float = 4000,
+    y_c: float = 0,
+    z_c: float = 0,
+    res: float | str = "default",
+) -> NerveMshCreator:
     """
     returns the corresponding mesh from a nrv.facsicle
     """
@@ -31,16 +31,17 @@ def mesh_from_electrode(
         elec.parameter_model(mesh, res=res)
     return mesh
 
+
 def mesh_from_extracellular_context(
-    extracel_context:FEM_stimulation,
-    mesh:NerveMshCreator|None=None,
-    Length:float=10000,
-    Outer_D:float=5,
-    Nerve_D:float=4000,
-    y_c:float=0,
-    z_c:float=0,
-    res_elec:list[float]|float|str="default",
-)->NerveMshCreator:
+    extracel_context: FEM_stimulation,
+    mesh: NerveMshCreator | None = None,
+    Length: float = 10000,
+    Outer_D: float = 5,
+    Nerve_D: float = 4000,
+    y_c: float = 0,
+    z_c: float = 0,
+    res_elec: list[float] | float | str = "default",
+) -> NerveMshCreator:
     """
     returns the corresponding mesh from a nrv.facsicle
     """
@@ -75,20 +76,20 @@ def mesh_from_extracellular_context(
 
 
 def mesh_from_fascicle(
-    fascicle:fascicle,
-    mesh:NerveMshCreator|None=None,
-    Length:float=10000,
-    Outer_D:float=5,
-    Nerve_D:float=4000,
-    y_c:float=0,
-    z_c:float=0,
-    add_axons:bool=True,
-    add_context:bool=False,
-    res_nerve:float|str="default",
-    res_fasc:float|str="default",
-    res_ax:list[float]|float|str="default",
-    res_elec:list[float]|float|str="default",
-)->NerveMshCreator:
+    fascicle: fascicle,
+    mesh: NerveMshCreator | None = None,
+    Length: float = 10000,
+    Outer_D: float = 5,
+    Nerve_D: float = 4000,
+    y_c: float = 0,
+    z_c: float = 0,
+    add_axons: bool = True,
+    add_context: bool = False,
+    res_nerve: float | str = "default",
+    res_fasc: float | str = "default",
+    res_ax: list[float] | float | str = "default",
+    res_elec: list[float] | float | str = "default",
+) -> NerveMshCreator:
     """
     returns the corresponding mesh from a nrv.facsicle
     """
@@ -119,28 +120,26 @@ def mesh_from_fascicle(
             mye = bool(fascicle.axons_type[i_ax])
             if isinstance(res_ax, str) and res_ax != "default":
                 res_ax = eval(str(fascicle.axons_diameter[i_ax]) + res_ax)
-            mesh.reshape_axon(d=ax_d, y=ax_y, z=ax_z, myelinated=mye, node_sift=node_sift, res=res_ax)
+            mesh.reshape_axon(
+                d=ax_d, y=ax_y, z=ax_z, myelinated=mye, node_sift=node_sift, res=res_ax
+            )
     if add_context and fascicle.extra_stim is not None:
         mesh = mesh_from_extracellular_context(
-            fascicle.extra_stim,
-            mesh=mesh,
-            res_elec=res_elec
+            fascicle.extra_stim, mesh=mesh, res_elec=res_elec
         )
     return mesh
 
 
 def mesh_from_nerve(
-    nerve:nerve,
-    length:float=None,
-    add_axons:bool=True,
-    res_nerve:float|str="default",
-    res_fasc:list[float]|float|str="default",
-    res_ax:list[float]|float|str="default",
-    res_elec:list[float]|float|str="default",
-)->NerveMshCreator:
-    """
-    
-    """
+    nerve: nerve,
+    length: float = None,
+    add_axons: bool = True,
+    res_nerve: float | str = "default",
+    res_fasc: list[float] | float | str = "default",
+    res_ax: list[float] | float | str = "default",
+    res_elec: list[float] | float | str = "default",
+) -> NerveMshCreator:
+    """ """
     nerve = load_any(nerve, extracel_context=True)
     length = length or nerve.L
     mesh = NerveMshCreator(
@@ -173,8 +172,6 @@ def mesh_from_nerve(
         )
     if "extra_stim" in nerve.__dict__ and nerve.extra_stim is not None:
         mesh = mesh_from_extracellular_context(
-            nerve.extra_stim,
-            mesh=mesh,
-            res_elec=res_elec
-            )
+            nerve.extra_stim, mesh=mesh, res_elec=res_elec
+        )
     return mesh
diff --git a/nrv/utils/__init__.py b/nrv/utils/__init__.py
index 7b362e80..67eafd8f 100644
--- a/nrv/utils/__init__.py
+++ b/nrv/utils/__init__.py
@@ -1,2 +1,103 @@
-""" NeuRon Virtualizer, large scale modeling of Peripheral Nervous System with random stimulation waveforms"""
-""" Utils librairy"""
+""" Utils: general purpose functions and classes
+
+utils provides some classes and functions for runing and interconnecting code
+from the scientific sub-packages.
+"""
+
+from ._misc import (
+    distance_point2point,
+    distance_point2line,
+    nearest_idx,
+    nearest_greater_idx,
+    in_tol,
+    get_perineurial_thickness,
+    membrane_capacitance_from_model,
+    compute_complex_admitance,
+)
+from ._nrv_function import (
+    nrv_function,
+    function_1D,
+    gaussian,
+    gate,
+    function_2D,
+    ackley,
+    beale,
+    goldstein_price,
+    booth,
+    bukin6,
+    function_ND,
+    Id,
+    rosenbock,
+    rastrigin,
+    sphere,
+    cost_evaluation,
+    nrv_interp,
+    MeshCallBack,
+)
+
+from ._units import (
+    print_default_nrv_unit,
+    from_nrv_unit,
+    to_nrv_unit,
+    convert,
+    sci_round,
+)
+
+from ._stimulus import (
+    is_stim,
+    set_common_time_series,
+    get_equal_timing_copies,
+    datfile_2_stim,
+    stimulus,
+)
+
+
+submodules = []
+
+classes = [
+    "nrv_function",
+    "function_1D",
+    "gaussian",
+    "gate",
+    "function_2D",
+    "ackley",
+    "beale",
+    "goldstein_price",
+    "booth",
+    "bukin6",
+    "function_ND",
+    "Id",
+    "rosenbock",
+    "rastrigin",
+    "sphere",
+    "cost_evaluation",
+    "nrv_interp",
+    "MeshCallBack",
+    "stimulus",
+]
+
+functions = [
+    "distance_point2point",
+    "distance_point2line",
+    "nearest_idx",
+    "nearest_greater_idx",
+    "in_tol",
+    "get_perineurial_thickness",
+    "membrane_capacitance_from_model",
+    "compute_complex_admitance",
+    "print_default_nrv_unit",
+    "from_nrv_unit",
+    "to_nrv_unit",
+    "convert",
+    "sci_round",
+    "is_stim",
+    "set_common_time_series",
+    "get_equal_timing_copies",
+    "datfile_2_stim",
+]
+
+__all__ = []
+
+__all__ += submodules
+__all__ += classes
+__all__ += functions
diff --git a/nrv/utils/misc.py b/nrv/utils/_misc.py
similarity index 82%
rename from nrv/utils/misc.py
rename to nrv/utils/_misc.py
index 7b136b66..91290423 100644
--- a/nrv/utils/misc.py
+++ b/nrv/utils/_misc.py
@@ -57,14 +57,14 @@ def distance_point2line(x_p, y_p, a, b):
     return d
 
 
-def nearest_idx(array:NDArray, val:float ) -> int:
+def nearest_idx(array: NDArray, val: float) -> int:
     """
-    Return index of neareast value 
+    Return index of neareast value
 
     Parameters
     ----------
     array : NDArray
-        array of values 
+        array of values
     val : float
         neareast value to find index
 
@@ -73,16 +73,17 @@ def nearest_idx(array:NDArray, val:float ) -> int:
     int
         index of the neareast value
     """
-    return (np.absolute(array-val)).argmin()
- 
-def nearest_greater_idx(array:NDArray, val:float ) -> int:
+    return (np.absolute(array - val)).argmin()
+
+
+def nearest_greater_idx(array: NDArray, val: float) -> int:
     """
-    Return index of neareast greater value 
+    Return index of neareast greater value
 
     Parameters
     ----------
     array : NDArray
-        array of values 
+        array of values
     val : float
         neareast greater value to find index
 
@@ -91,20 +92,21 @@ def nearest_greater_idx(array:NDArray, val:float ) -> int:
     int
         index of the neareast greater value
     """
-    diff = array-val
-    mask = np.ma.MaskedArray(diff, diff<0)
+    diff = array - val
+    mask = np.ma.MaskedArray(diff, diff < 0)
     return mask.argmin()
 
-def in_tol(test:float,ref:float,tol:float = 0.1) -> bool:
+
+def in_tol(test: float, ref: float, tol: float = 0.1) -> bool:
     """
-    Check if a value is equal to a value +- a tol (excluded). 
+    Check if a value is equal to a value +- a tol (excluded).
 
     Parameters
     ----------
     test : float
         Value to test
     ref : float
-        Reference value 
+        Reference value
     tol : float, optional
         Tolerance, expressed as a proportion of ref. By default 0.1
 
@@ -113,14 +115,15 @@ def in_tol(test:float,ref:float,tol:float = 0.1) -> bool:
     bool
         True if within tolerance, else False.
     """
-    up_bound = ref *(1+tol)
-    down_bound =  ref *(1-tol)
-    return (np.abs(test)<up_bound and np.abs(test)>down_bound)
+    up_bound = ref * (1 + tol)
+    down_bound = ref * (1 - tol)
+    return np.abs(test) < up_bound and np.abs(test) > down_bound
+
 
 ####################################################
 ############# nmod related functions ###############
 ####################################################
-def get_perineurial_thickness(fasc_d:float, nerve_type:str="default") -> float:
+def get_perineurial_thickness(fasc_d: float, nerve_type: str = "default") -> float:
     """
     Return a fascicle's perineurium thickness from its diameter.
     Relationship extract from [1]
@@ -165,17 +168,16 @@ def get_perineurial_thickness(fasc_d:float, nerve_type:str="default") -> float:
 
     return fasc_d * thpc
 
+
 def membrane_capacitance_from_model(model):
-    if model in ["MRG", "Gaines_motor", "Gaines_sensory" ]:
+    if model in ["MRG", "Gaines_motor", "Gaines_sensory"]:
         return 2
     if "Schild" in model:
         return 1.326291192
     return 1
 
 
-
-
-def compute_complex_admitance(f:float, g:float, fc:float)->complex:
+def compute_complex_admitance(f: float, g: float, fc: float) -> complex:
     """
     compute the complex admitance of a first oder system (of cutoff frequency fc and conductivity g) at a given frequency f
 
@@ -193,4 +195,4 @@ def compute_complex_admitance(f:float, g:float, fc:float)->complex:
     complex
         complex admitance
     """
-    return g*(1+1j*f/fc)
\ No newline at end of file
+    return g * (1 + 1j * f / fc)
diff --git a/nrv/utils/nrv_function.py b/nrv/utils/_nrv_function.py
similarity index 84%
rename from nrv/utils/nrv_function.py
rename to nrv/utils/_nrv_function.py
index a404a2a9..0e680a82 100644
--- a/nrv/utils/nrv_function.py
+++ b/nrv/utils/_nrv_function.py
@@ -1,15 +1,16 @@
 """
 NRV-:class:`nrv_function` handling.
 """
+
 from abc import abstractmethod
 
 import numpy as np
 from scipy.interpolate import CubicHermiteSpline, interp1d
 from scipy.special import erf
 
-from ..backend.file_handler import json_dump, json_load
-from ..backend.log_interface import rise_warning, rise_error
-from ..backend.NRV_Class import NRV_class, is_empty_iterable
+from ..backend._file_handler import json_dump, json_load
+from ..backend._log_interface import rise_warning, rise_error
+from ..backend._NRV_Class import NRV_class, is_empty_iterable
 
 #############################
 ## sigma functions classes ##
@@ -156,9 +157,9 @@ class gaussian(function_1D):
 
         f(x) = e^{-\frac{(x-\mu)^2}{2*\sigma^2}}
     """
+
     def __init__(self, mu=0, sigma=1):
-        """
-        """
+        """ """
         super().__init__()
         self.mu = mu
         self.sigma = sigma
@@ -214,7 +215,6 @@ def __init__(self):
         self.f_type = "function_2D"
         self.dim = 2
 
-
     @staticmethod
     def call_method(self, X):
         return 1
@@ -311,7 +311,6 @@ def __init__(self):
         self.f_type = "function_ND"
         self.dim = "N"
 
-
     @staticmethod
     def call_method(self, *X):
         return 1
@@ -410,6 +409,40 @@ def __call__(self, results, **kwargs) -> float:
 ####################### interpolation ######################
 ###############################################################
 class nrv_interp(nrv_function):
+    """
+    Interpolator based on scipy.interpolate
+
+    Parameters
+    ----------
+    X_values    : (N,) array_like
+        A 1-D array of real values
+    Y_values    :(…,N,…) array_like
+        A N-D array of real values. The length of y along the interpolation
+        axis must be equal to the length of x.
+    kind        : str
+        kind of interpolation which should be used, by default "linear" possible values:
+            - scipy interp1d kinds (see nrv.spy_interp1D_kind)
+            - {'hermite', 'cardinal', 'catmull-rom'} for respective
+              cubic spline interpollation
+    dx
+        if minimal distance between 2 consecutive points, by default 0.01 interpolator
+        custumize intepolation function if None kind is use to set the interpolator,
+        by default None
+    dxdy
+        if kind is 'hermite', derivative vector (see scipy.interpolate.CubicHermiteSpline),
+        by default None
+    scale
+        if kind is 'cardinal', scale to use for derivative vector, by default None
+    columns       : int or array_like
+        columns on which apply the interpolation when class called
+        if [] iterpolation done on the whole vector,by default []
+
+    Returns
+    -------
+    output  :  tuple(3)
+        (domain, cell_tag, facet_tag)
+    """
+
     def __init__(
         self,
         X_values,
@@ -421,39 +454,6 @@ def __init__(
         scale=None,
         columns=[],
     ):
-        """
-        Interpolator based on scipy.interpolate
-        Parameters
-        ----------
-        X_values    : (N,) array_like
-            A 1-D array of real values
-        Y_values    :(…,N,…) array_like
-            A N-D array of real values. The length of y along the interpolation
-            axis must be equal to the length of x.
-        kind        : str
-            kind of interpolation which should be used, by default "linear"
-            possible values:    - scipy interp1d kinds (see nrv.spy_interp1D_kind)
-                                - {'hermite', 'cardinal', 'catmull-rom'} for respective
-                                  cubic spline interpollation
-        dx
-            if minimal distance between 2 consecutive points, by default 0.01
-        interpolator
-            custumize intepolation function if None kind is use to set the interpolator,
-            by default None
-        dxdy
-            if kind is 'hermite', derivative vector (see scipy.interpolate.CubicHermiteSpline),
-            by default None
-        scale
-            if kind is 'cardinal', scale to use for derivative vector, by default None
-        columns       : int or array_like
-            columns on which apply the interpolation when class called
-            if [] iterpolation done on the whole vector,by default []
-
-        Returns
-        -------
-        output  :  tuple(3)
-            (domain, cell_tag, facet_tag)
-        """
         super().__init__()
         self.f_type = "nrv_interp"
         # General parameters
@@ -544,39 +544,39 @@ def __add__(self, b):
                 rise_error(
                     "Not implemented: operations of nrv_iterp with different X_scale"
                 )
-        else: 
-            Y = self.Y_values+b
+        else:
+            Y = self.Y_values + b
         return nrv_interp(
-            X_values = self.X_values,
-            Y_values = Y,
-            interpolator = self.interpolator,
-            kind = self.kind,
-            dx = self.dx,
-            dxdy = None,
-            scale = self.scale,
-            columns = self.columns,
+            X_values=self.X_values,
+            Y_values=Y,
+            interpolator=self.interpolator,
+            kind=self.kind,
+            dx=self.dx,
+            dxdy=None,
+            scale=self.scale,
+            columns=self.columns,
         )
 
     def __mul__(self, b):
         if isinstance(b, nrv_interp):
             if np.allclose(b.X_values, self.X_values):
-                Y =  self.Y_values*b.Y_values
+                Y = self.Y_values * b.Y_values
                 # TO ADD: computation of dxdy when both are set
             else:
                 rise_error(
                     "Not implemented: operations of nrv_iterp with different X_scale"
                 )
-        else: 
-            Y = self.Y_values*b
+        else:
+            Y = self.Y_values * b
         return nrv_interp(
-            X_values = self.X_values,
-            Y_values = Y,
-            interpolator = self.interpolator,
-            kind = self.kind,
-            dx = self.dx,
-            dxdy = None,
-            scale = self.scale,
-            columns = self.columns,
+            X_values=self.X_values,
+            Y_values=Y,
+            interpolator=self.interpolator,
+            kind=self.kind,
+            dx=self.dx,
+            dxdy=None,
+            scale=self.scale,
+            columns=self.columns,
         )
 
     def __truediv__(self, b):
@@ -592,16 +592,16 @@ def __truediv__(self, b):
                     "operations of nrv_iterp with different X_scale",
                 )
         else:
-            Y = self.Y_values/b
+            Y = self.Y_values / b
         return nrv_interp(
-            X_values = self.X_values,
-            Y_values = Y,
-            interpolator = self.interpolator,
-            kind = self.kind,
-            dx = self.dx,
-            dxdy = None,
-            scale = self.scale,
-            columns = self.columns,
+            X_values=self.X_values,
+            Y_values=Y,
+            interpolator=self.interpolator,
+            kind=self.kind,
+            dx=self.dx,
+            dxdy=None,
+            scale=self.scale,
+            columns=self.columns,
         )
 
     def __rtruediv__(self, b):
@@ -609,7 +609,7 @@ def __rtruediv__(self, b):
             rise_error(ZeroDivisionError, " float division by zero in Python")
         if isinstance(b, nrv_interp):
             if np.allclose(b.X_values, self.X_values):
-                Y = b.Y_values/self.Y_values
+                Y = b.Y_values / self.Y_values
                 # TO ADD: computation of dxdy when both are set
             else:
                 rise_error(
@@ -617,28 +617,27 @@ def __rtruediv__(self, b):
                     "operations of nrv_iterp with different X_scale",
                 )
         else:
-            Y = b/self.Y_values
+            Y = b / self.Y_values
         return nrv_interp(
-            X_values = self.X_values,
-            Y_values = Y,
-            interpolator = self.interpolator,
-            kind = self.kind,
-            dx = self.dx,
-            dxdy = self.dxdy,
-            scale = self.scale,
-            columns = self.columns,
+            X_values=self.X_values,
+            Y_values=Y,
+            interpolator=self.interpolator,
+            kind=self.kind,
+            dx=self.dx,
+            dxdy=self.dxdy,
+            scale=self.scale,
+            columns=self.columns,
         )
 
-
     def __radd__(self, b):
         return self.__add__(b)
 
     def __rmul__(self, b):
         return self.__mul__(b)
-    
+
     def __sub__(self, b):
         return self.__add__(-b)
-    
+
     def __rsub__(self, b):
         return self.__sub__(b)
 
diff --git a/nrv/utils/saving_handler.py b/nrv/utils/_saving_handler.py
similarity index 81%
rename from nrv/utils/saving_handler.py
rename to nrv/utils/_saving_handler.py
index 6b8b4306..24b3aa2c 100644
--- a/nrv/utils/saving_handler.py
+++ b/nrv/utils/_saving_handler.py
@@ -3,15 +3,17 @@
 Authors: Florian Kolbl / Roland Giraud / Louis Regnacq / Thomas Couppey
 (c) ETIS - University Cergy-Pontoise - CNRS
 """
-from ..backend.MCore import *
-from ..fmod.electrodes import *
-from ..fmod.extracellular import *
-from ..fmod.materials import *
-from ..fmod.stimulus import *
-from ..nmod.axons import *
-from ..nmod.fascicles import *
-from ..nmod.myelinated import *
-from ..nmod.unmyelinated import *
+
+from ..backend._MCore import *
+from ..fmod._electrodes import *
+from ..fmod._extracellular import *
+from ..fmod._materials import *
+from ._stimulus import *
+from ..nmod._axons import *
+from ..nmod._fascicles import *
+from ..nmod._myelinated import *
+from ..nmod._unmyelinated import *
+from ..backend._log_interface import rise_warning
 
 ###############################################################
 #########################  Loaders  ###########################
@@ -29,6 +31,7 @@ def load_any_fascicle(
     data    : str or dict
         json file path or dictionary containing fascicle information
     """
+    rise_warning(DeprecationWarning, ": use load any intead")
     synchronize_processes()
     if type(data) == str:
         fasc_dic = json_load(data)
@@ -62,6 +65,7 @@ def load_any_axon(
     data    : str or dict
         json file path or dictionary containing axon information
     """
+    rise_warning(DeprecationWarning, ": use load_any function intead")
     if type(data) == str:
         ax_dic = json_load(data)
     else:
diff --git a/nrv/fmod/stimulus.py b/nrv/utils/_stimulus.py
similarity index 98%
rename from nrv/fmod/stimulus.py
rename to nrv/utils/_stimulus.py
index f9d6f5f0..2b36eda7 100644
--- a/nrv/fmod/stimulus.py
+++ b/nrv/utils/_stimulus.py
@@ -1,12 +1,13 @@
 """
 NRV-:class:`.stimulus` handling.
 """
+
 import faulthandler
 
 import numpy as np
 
-from ..backend.log_interface import pass_info, rise_warning, rise_error
-from ..backend.NRV_Class import NRV_class
+from ..backend._log_interface import pass_info, rise_warning, rise_error
+from ..backend._NRV_Class import NRV_class
 import matplotlib.pyplot as plt
 
 # enable faulthandler to ease "segmentation faults" debug
@@ -218,7 +219,7 @@ def snap_time(self, dt_min):
         self.s = self.s[i_mask]
         self.t = self.t[i_mask]
 
-    def plot(self, ax:plt.axes, scatter=False, **ax_kwargs):
+    def plot(self, ax: plt.axes, scatter=False, **ax_kwargs):
         """
         Plot the stimulus
         """
@@ -227,8 +228,6 @@ def plot(self, ax:plt.axes, scatter=False, **ax_kwargs):
         else:
             ax.step(self.t, self.s, where="post", **ax_kwargs)
 
-
-
     #####################
     ## special methods ##
     #####################
@@ -547,15 +546,15 @@ def square(self, start, duration, freq, amplitude, offset, anod_first=False):
             sampling time period to generate the sinusoidal shape. If equal to 0,
             dt is automatically set to match 100 samples per sinusoid period by default set to 0
         """
-        Nb_pts = 2*int(duration / freq) - 1
-        dt = 1 / (2*freq)
+        Nb_pts = 2 * int(duration / freq) - 1
+        dt = 1 / (2 * freq)
         t = np.linspace(0, duration, num=Nb_pts)
-        s = np.ones(Nb_pts)*amplitude
+        s = np.ones(Nb_pts) * amplitude
         k_start = 0
         if anod_first:
             k_start = 1
         for k in range(k_start, len(s), 2):
-            s[k]*=-1
+            s[k] *= -1
         s += offset
         self.concatenate(s, t, t_shift=start)
 
diff --git a/nrv/utils/units.py b/nrv/utils/_units.py
similarity index 99%
rename from nrv/utils/units.py
rename to nrv/utils/_units.py
index 1efa601b..3095a0cb 100644
--- a/nrv/utils/units.py
+++ b/nrv/utils/_units.py
@@ -33,6 +33,7 @@
             - F, mF, pF, nF
 
 """
+
 import numpy as np
 from copy import deepcopy
 
@@ -212,6 +213,7 @@ def to_nrv_unit(value, unit):
     else:
         return value * unit
 
+
 def convert(value, unitin, unitout):
     """
     Convert a quantity ``value`` from ``unitin`` to ``unitout``.
@@ -246,7 +248,8 @@ def convert(value, unitin, unitout):
         return cp_value
     else:
         return from_nrv_unit(to_nrv_unit(value, unitin), unitout)
-    
+
+
 def sci_round(value, digits=3):
     """
     Rounds one or several values to ``digits`` significant digits.
diff --git a/nrv/utils/cell/__init__.py b/nrv/utils/cell/__init__.py
deleted file mode 100644
index 0012348b..00000000
--- a/nrv/utils/cell/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-""" NeuRon Virtualizer, large scale modeling of Peripheral Nervous System with random stimulation waveforms"""
-""" Utils.Cell librairy"""
diff --git a/nrv/utils/fascicle/__init__.py b/nrv/utils/fascicle/__init__.py
deleted file mode 100644
index 0346971e..00000000
--- a/nrv/utils/fascicle/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-""" NeuRon Virtualizer, large scale modeling of Peripheral Nervous System with random stimulation waveforms"""
-""" Utils.fascicle librairy"""
diff --git a/setup.py b/setup.py
index 3b24ace3..ed3ec75b 100644
--- a/setup.py
+++ b/setup.py
@@ -83,11 +83,10 @@
         "nrv.nmod.results",
         "nrv.optim",
         "nrv.optim.optim_utils",
+        "nrv.ui",
         "nrv.utils",
-        "nrv.utils.cell",
-        "nrv.utils.fascicle",
     ],
-    
+
     # non python data to keep
     package_data={
         "nrv": ["nrv2calm"],
@@ -133,6 +132,6 @@
         "tqdm",
         "psutil",
     ],  # external packages as dependencies
-    python_requires=">=3.10",
+    python_requires=">=3.12",
     scripts=['./nrv/nrv2calm',"./tests/NRV_test"]        #script
 )


Test patch:
diff --git a/tests/log_NRV_test.txt b/tests/log_NRV_test.txt
index 2d4221af..5a50d38c 100644
--- a/tests/log_NRV_test.txt
+++ b/tests/log_NRV_test.txt
@@ -2,3 +2,7 @@
 --- list of failed tests : [070_test_fascicular_state.py, 115_test_FENICS_eval_field.py, 160_test_FENICS_NerveMshCreator_myelinated.py, 161_test_FENICS_NerveMshCreator_myelinated.py, 162_test_FENICS_NerveMshCreator_myelinated_method2.py, 165_test_layered_material.py, 403_test_eit_reconstruc.py, 404_test_sigma_func copy.py, 518_test_nerves_results.py]
 --- Bugs in NRV, please consider reported errors before simulations
 --- list of failed tests : [160_test_FENICS_NerveMshCreator_myelinated.py, 165_test_layered_material.py]
+--- Bugs in NRV, please consider reported errors before simulations
+--- list of failed tests : [034_test_Sundt.py, 035_test_Tigerholm.py, 036_test_schild_94.py, 037_test_schild_97.py, 070_test_fascicle_block_summary.py, 092_test_g_recorders_MRG.py, 093_test_recorders_Gaines.py, 098_test_rec_all_g_Ext_Gaines.py, 160_test_FENICS_NerveMshCreator_myelinated.py, 163_test_FENICS_FEMsim_myelinated.py, 165_test_layered_material.py, 307_plot_nerve_KES.py, 308_raster_plot_nerve_KES.py, 531_test_colormap_plot.py]
+--- Bugs in NRV, please consider reported errors before simulations
+--- list of failed tests : [207_test_cost_function_fasc.py]
diff --git a/tests/unitary_tests/033_test_Rattay_aberham.py b/tests/unitary_tests/033_test_Rattay_aberham.py
index 48f07435..0ce7962b 100644
--- a/tests/unitary_tests/033_test_Rattay_aberham.py
+++ b/tests/unitary_tests/033_test_Rattay_aberham.py
@@ -28,8 +28,6 @@
 
 fig, ax = plt.subplots()
 results.plot_x_t(ax)
-plt.show()
-exit()
 plt.savefig('./unitary_tests/figures/25_C.png')
 
 plt.figure()
diff --git a/tests/unitary_tests/070_test_fascicle_block_summary.py b/tests/unitary_tests/070_test_fascicle_block_summary.py
index c7dac061..4b8cab2d 100644
--- a/tests/unitary_tests/070_test_fascicle_block_summary.py
+++ b/tests/unitary_tests/070_test_fascicle_block_summary.py
@@ -62,13 +62,13 @@
 #f_results.save(save=True,fname="test.json")
 #f_results = nrv.load_any("test.json")
 
-fig,ax = plt.subplots(1)
-fig.set_size_inches(5, 5)
-
-f_results.plot_block_summary(ax, AP_start = t_start, freq = block_freq, num=True)
+if nrv.MCH.do_master_only_work():
+    fig,ax = plt.subplots(1)
+    fig.set_size_inches(5, 5)
+    f_results.plot_block_summary(ax, AP_start = t_start, freq = block_freq, num=True)
 
-fig.tight_layout()
-fig.savefig("./unitary_tests/figures/70_A.png")
+    fig.tight_layout()
+    fig.savefig("./unitary_tests/figures/70_A.png")
 #plt.show()
 
 #print(f_results)
diff --git a/tests/unitary_tests/150_test_FENxCOM_based_stimulation.py b/tests/unitary_tests/150_test_FENxCOM_based_stimulation.py
index 038f2db6..18976692 100644
--- a/tests/unitary_tests/150_test_FENxCOM_based_stimulation.py
+++ b/tests/unitary_tests/150_test_FENxCOM_based_stimulation.py
@@ -65,4 +65,4 @@
 plt.plot(x, fen_elec_1.footprint,color='g',label='FEniCS')
 plt.legend()
 plt.savefig('./unitary_tests/figures/150_A.png')
-plt.show()
+#plt.show()
diff --git a/tests/unitary_tests/200_test_optimisation_0.py b/tests/unitary_tests/200_test_optimisation_0.py
index 920cad63..05f8c60a 100644
--- a/tests/unitary_tests/200_test_optimisation_0.py
+++ b/tests/unitary_tests/200_test_optimisation_0.py
@@ -1,4 +1,4 @@
-import nrv.utils.nrv_function as oobj
+import nrv.utils._nrv_function as oobj
 import numpy as np
 import matplotlib.pyplot as plt
 
diff --git a/tests/unitary_tests/210_test_pso_optimizer.py b/tests/unitary_tests/210_test_pso_optimizer.py
index ddb08eff..e7eca50a 100644
--- a/tests/unitary_tests/210_test_pso_optimizer.py
+++ b/tests/unitary_tests/210_test_pso_optimizer.py
@@ -1,5 +1,5 @@
 import nrv
-from nrv.utils.nrv_function import sphere, rosenbock, rastrigin
+from nrv.utils._nrv_function import sphere, rosenbock, rastrigin
 
 import matplotlib.pyplot as plt
 
diff --git a/tests/unitary_tests/211_test_scipy_default_optimizer.py b/tests/unitary_tests/211_test_scipy_default_optimizer.py
index 2e868152..81261caa 100644
--- a/tests/unitary_tests/211_test_scipy_default_optimizer.py
+++ b/tests/unitary_tests/211_test_scipy_default_optimizer.py
@@ -1,5 +1,5 @@
 import nrv
-from nrv.utils.nrv_function import sphere, rosenbock
+from nrv.utils._nrv_function import sphere, rosenbock
 
 import matplotlib.pyplot as plt
 
diff --git a/tests/unitary_tests/212_test_scipy_Powell_optimizer.py b/tests/unitary_tests/212_test_scipy_Powell_optimizer.py
index 69851eec..202dc3a3 100644
--- a/tests/unitary_tests/212_test_scipy_Powell_optimizer.py
+++ b/tests/unitary_tests/212_test_scipy_Powell_optimizer.py
@@ -1,5 +1,5 @@
 import nrv
-from nrv.utils.nrv_function import sphere, rosenbock
+from nrv.utils._nrv_function import sphere, rosenbock
 
 import matplotlib.pyplot as plt
 
diff --git a/tests/unitary_tests/213_test_scipy_normalized.py b/tests/unitary_tests/213_test_scipy_normalized.py
index d4d218c3..56571e64 100644
--- a/tests/unitary_tests/213_test_scipy_normalized.py
+++ b/tests/unitary_tests/213_test_scipy_normalized.py
@@ -1,5 +1,5 @@
 import nrv
-from nrv.utils.nrv_function import sphere, rosenbock, rastrigin
+from nrv.utils._nrv_function import sphere, rosenbock, rastrigin
 import numpy as np
 import matplotlib.pyplot as plt
 
diff --git a/tests/unitary_tests/221_test_pso_postprocessing.py b/tests/unitary_tests/221_test_pso_postprocessing.py
index c5b1ea9e..914eaedb 100644
--- a/tests/unitary_tests/221_test_pso_postprocessing.py
+++ b/tests/unitary_tests/221_test_pso_postprocessing.py
@@ -1,5 +1,5 @@
 import nrv
-from nrv.utils.nrv_function import sphere, rosenbock, rastrigin
+from nrv.utils._nrv_function import sphere, rosenbock, rastrigin
 import numpy as np
 import matplotlib.pyplot as plt
 
diff --git a/tests/unitary_tests/222_test_harmonic_context_modifier.py b/tests/unitary_tests/222_test_harmonic_context_modifier.py
index 6b68106e..dfcf1d8d 100644
--- a/tests/unitary_tests/222_test_harmonic_context_modifier.py
+++ b/tests/unitary_tests/222_test_harmonic_context_modifier.py
@@ -41,7 +41,7 @@ def plot_stim(stim, t_stop=None, N_plot=10000):
     test_stim = ax.extra_stim.stimuli[0]
     '''
     plt.plot(test_stim.t,test_stim.s)
-    plt.show()
+    #plt.show()
     exit()
     '''
     results = ax(t_sim=t_sim)
diff --git a/tests/unitary_tests/225_test_harmonic_pw_context_modifier.py b/tests/unitary_tests/225_test_harmonic_pw_context_modifier.py
index 6c44f834..7d46917d 100644
--- a/tests/unitary_tests/225_test_harmonic_pw_context_modifier.py
+++ b/tests/unitary_tests/225_test_harmonic_pw_context_modifier.py
@@ -41,7 +41,7 @@ def plot_stim(stim, t_stop=None, N_plot=10000):
     test_stim = ax.extra_stim.stimuli[0]
     '''
     plt.plot(test_stim.t,test_stim.s)
-    plt.show()
+    #plt.show()
     exit()
     '''
     results = ax(t_sim=t_sim)
diff --git a/tests/unitary_tests/301_test_nerve_OTF_PP.py b/tests/unitary_tests/301_test_nerve_OTF_PP.py
index 0713ca58..b2bf7c53 100644
--- a/tests/unitary_tests/301_test_nerve_OTF_PP.py
+++ b/tests/unitary_tests/301_test_nerve_OTF_PP.py
@@ -15,21 +15,21 @@ def test_oft_pp(results:nrv.axon_results, num=0):
 fascicle = nrv.fascicle(ID=test_num)
 
 # SHAM 1 axon fascicle
-fascicle.axons_diameter = np.asarray([5.7])
-fascicle.axons_type = np.asarray([1])
-fascicle.axons_y = np.asarray([0])
-fascicle.axons_z = np.asarray([0])
-fascicle.define_circular_contour(D=6)
+fascicle.axons_diameter = np.asarray([5.7, .5, 1])
+fascicle.axons_type = np.asarray([1, 0, 0])
+fascicle.axons_y = np.asarray([0, 0, 10])
+fascicle.axons_z = np.asarray([0, 10, 0])
+fascicle.define_circular_contour(D=50)
 fasc_dic = fascicle.save(save=False)
 
 for i in range(len(postproc)):
     id = test_num*10 + i
     nerve = nrv.nerve(Length=10000)
     nerve.set_ID(id)
-    nerve.add_fascicle(fasc_dic, ID=1, y=-6)
-    nerve.add_fascicle(fasc_dic, ID=2, y=6)
-    nerve.add_fascicle(fasc_dic, ID=3, z=-6)
-    nerve.add_fascicle(fasc_dic, ID=4, z=6)
+    nerve.add_fascicle(fasc_dic, ID=1, y=-50)
+    nerve.add_fascicle(fasc_dic, ID=2, y=50)
+    nerve.add_fascicle(fasc_dic, ID=3, z=-50)
+    nerve.add_fascicle(fasc_dic, ID=4, z=50)
     nerve.fit_circular_contour()
 
 
diff --git a/tests/unitary_tests/523_test_isBlocked.py b/tests/unitary_tests/523_test_isBlocked.py
index f378c64c..65d6ead4 100644
--- a/tests/unitary_tests/523_test_isBlocked.py
+++ b/tests/unitary_tests/523_test_isBlocked.py
@@ -61,5 +61,5 @@
 plt.xlim(0,results['tstop'])
 plt.ylim(0,results['L'])
 
-plt.show()
+#plt.show()
 
diff --git a/tests/unitary_tests/524_test_AP_analysis.py b/tests/unitary_tests/524_test_AP_analysis.py
index 3e8b49e5..7aded4fe 100644
--- a/tests/unitary_tests/524_test_AP_analysis.py
+++ b/tests/unitary_tests/524_test_AP_analysis.py
@@ -6,7 +6,6 @@
 d = 10
 L = 20000
 
-
 #No APs
 axon0 = nrv.myelinated(y,z,d,L,dt=0.005,rec='all')
 results = axon0.simulate(t_sim=8)
@@ -19,27 +18,31 @@
 if (results.count_APs()):
     print(f"AP propagation velocity: {results.getAPspeed()[0]}m/s")
 
-plt.figure()
-plt.scatter(results['V_mem_raster_time'],results['V_mem_raster_x_position'],s=80)
+
+fig, ax = plt.subplots(1)
+results.plot_x_t(ax)
+
+fig, ax = plt.subplots(1)
+results.raster_plot(ax,s=80)
+
 
 for x_AP,t_AP in zip(x_APs,t_APs):
-    plt.scatter(t_AP,x_AP)
+    ax.scatter(t_AP,x_AP)
     x_start,t_start = results.get_start_AP(x_AP,t_AP)
     x_max,t_xmax = results.get_xmax_AP(x_AP,t_AP)
     x_min,t_xmin = results.get_xmin_AP(x_AP,t_AP)
-    plt.scatter(t_start,x_start,s=10,c = 'k')
-    plt.scatter(x_max,t_xmax,s=10,c = 'g')
-    plt.scatter(x_min,t_xmin,s=10,c = 'b')
+    ax.scatter(t_start,x_start,s=10,c = 'k')
+    ax.scatter(t_xmax,x_max,s=10,c = 'g')
+    ax.scatter(t_xmin,x_min,s=10,c = 'b')
 
 if results.detect_AP_collisions():
     x_coll,t_coll,_ = results.get_collision_pts()
-    plt.scatter(t_coll,x_coll,s=50,c = 'r')
-
-plt.xlabel('time (ms)')
-plt.ylabel(r'position along the axon($\mu m$)')
-plt.xlim(0,results['tstop'])
-plt.savefig('./unitary_tests/figures/524_A.png')
+    ax.scatter(t_coll,x_coll,s=50,c = 'r')
 
+ax.set_xlabel('time (ms)')
+ax.set_ylabel(r'position along the axon($\mu m$)')
+ax.set_xlim(0,results['tstop'])
+fig.savefig('./unitary_tests/figures/524_A.png')
 
 #No collision
 axon1 = nrv.myelinated(y,z,d,L,dt=0.005,rec='all')
@@ -53,6 +56,7 @@
 
 results = axon1.simulate(t_sim=8)
 results.rasterize()
+
 x_APs,_,t_APs,_ = results.split_APs()
 print(f"Number of APs detected: {results.count_APs()}")
 print(f"APs reached end: {results.APs_reached_end()}")
@@ -61,26 +65,29 @@
 if (results.count_APs()):
     print(f"AP propagation velocity: {results.getAPspeed()[0]}m/s")
 
-plt.figure()
-plt.scatter(results['V_mem_raster_time'],results['V_mem_raster_x_position'],s=80)
+fig, ax = plt.subplots(1)
+results.plot_x_t(ax)
+
+fig, ax = plt.subplots(1)
+results.raster_plot(ax,s=80)
 
 for x_AP,t_AP in zip(x_APs,t_APs):
-    plt.scatter(t_AP,x_AP)
+    ax.scatter(t_AP,x_AP)
     x_start,t_start = results.get_start_AP(x_AP,t_AP)
     x_max,t_xmax = results.get_xmax_AP(x_AP,t_AP)
     x_min,t_xmin = results.get_xmin_AP(x_AP,t_AP)
-    plt.scatter(t_start,x_start,s=10,c = 'k')
-    plt.scatter(t_xmax,x_max,s=10,c = 'g')
-    plt.scatter(t_xmin,x_min,s=10,c = 'b')
+    ax.scatter(t_start,x_start,s=10,c = 'k')
+    ax.scatter(t_xmax,x_max,s=10,c = 'g')
+    ax.scatter(t_xmin,x_min,s=10,c = 'b')
 
 if results.detect_AP_collisions():
     x_coll,t_coll,_ = results.get_collision_pts()
-    plt.scatter(t_coll,x_coll,s=50,c = 'r')
+    ax.scatter(t_coll,x_coll,s=50,c = 'r')
 
-plt.xlabel('time (ms)')
-plt.ylabel(r'position along the axon($\mu m$)')
-plt.xlim(0,results['tstop'])
-plt.savefig('./unitary_tests/figures/524_B.png')
+ax.set_xlabel('time (ms)')
+ax.set_ylabel(r'position along the axon($\mu m$)')
+ax.set_xlim(0,results['tstop'])
+fig.savefig('./unitary_tests/figures/524_B.png')
 
 
 #with AP collision
@@ -106,28 +113,29 @@
 if (results.count_APs()):
     print(f"AP propagation velocity: {results.getAPspeed()[0]}m/s")
 
+fig, ax = plt.subplots(1)
+results.plot_x_t(ax)
 
-plt.figure()
-plt.scatter(results['V_mem_raster_time'],results['V_mem_raster_x_position'],s=80)
+fig, ax = plt.subplots(1)
+results.raster_plot(ax,s=80)
 
 for x_AP,t_AP in zip(x_APs,t_APs):
-    plt.scatter(t_AP,x_AP)
+    ax.scatter(t_AP,x_AP)
     x_start,t_start = results.get_start_AP(x_AP,t_AP)
     x_max,t_xmax = results.get_xmax_AP(x_AP,t_AP)
     x_min,t_xmin = results.get_xmin_AP(x_AP,t_AP)
-    plt.scatter(t_start,x_start,s=10,c = 'k')
-    plt.scatter(t_xmax,x_max,s=10,c = 'g')
-    plt.scatter(t_xmin,x_min,s=10,c = 'b')
+    ax.scatter(t_start,x_start,s=10,c = 'k')
+    ax.scatter(t_xmax,x_max,s=10,c = 'g')
+    ax.scatter(t_xmin,x_min,s=10,c = 'b')
 
 if results.detect_AP_collisions():
     x_coll,t_coll,_ = results.get_collision_pts()
-    plt.scatter(t_coll,x_coll,s=50,c = 'r')
-
-plt.xlabel('time (ms)')
-plt.ylabel(r'position along the axon($\mu m$)')
-plt.xlim(0,results['tstop'])
-plt.savefig('./unitary_tests/figures/524_C.png')
+    ax.scatter(t_coll,x_coll,s=50,c = 'r')
 
+ax.set_xlabel('time (ms)')
+ax.set_ylabel(r'position along the axon($\mu m$)')
+ax.set_xlim(0,results['tstop'])
+fig.savefig('./unitary_tests/figures/524_C.png')
 
 
 axon3 = nrv.myelinated(y,z,d,L,dt=0.005,rec='all')
@@ -146,26 +154,29 @@
 if (results.count_APs()):
     print(f"AP propagation velocity: {results.getAPspeed()[0]}m/s")
 
-plt.figure()
-plt.scatter(results['V_mem_raster_time'],results['V_mem_raster_x_position'],s=80)
+fig, ax = plt.subplots(1)
+results.plot_x_t(ax)
+
+fig, ax = plt.subplots(1)
+results.raster_plot(ax,s=80)
 
 for x_AP,t_AP in zip(x_APs,t_APs):
-    plt.scatter(t_AP,x_AP)
+    ax.scatter(t_AP,x_AP)
     x_start,t_start = results.get_start_AP(x_AP,t_AP)
     x_max,t_xmax = results.get_xmax_AP(x_AP,t_AP)
     x_min,t_xmin = results.get_xmin_AP(x_AP,t_AP)
-    plt.scatter(t_start,x_start,s=10,c = 'k')
-    plt.scatter(t_xmax,x_max,s=10,c = 'g')
-    plt.scatter(t_xmin,x_min,s=10,c = 'b')
+    ax.scatter(t_start,x_start,s=10,c = 'k')
+    ax.scatter(t_xmax,x_max,s=10,c = 'g')
+    ax.scatter(t_xmin,x_min,s=10,c = 'b')
 
 if results.detect_AP_collisions():
     x_coll,t_coll,_ = results.get_collision_pts()
-    plt.scatter(t_coll,x_coll,s=50,c = 'r')
+    ax.scatter(t_coll,x_coll,s=50,c = 'r')
 
-plt.xlabel('time (ms)')
-plt.ylabel(r'position along the axon($\mu m$)')
-plt.xlim(0,results['tstop'])
-plt.savefig('./unitary_tests/figures/524_D.png')
+ax.set_xlabel('time (ms)')
+ax.set_ylabel(r'position along the axon($\mu m$)')
+ax.set_xlim(0,results['tstop'])
+fig.savefig('./unitary_tests/figures/524_D.png')
 
 
 axon4 = nrv.myelinated(y,z,d,L,dt=0.005,rec='all')
@@ -186,26 +197,29 @@
 if (results.count_APs()):
     print(f"AP propagation velocity: {results.getAPspeed()[0]}m/s")
 
-plt.figure()
-plt.scatter(results['V_mem_raster_time'],results['V_mem_raster_x_position'],s=80)
+fig, ax = plt.subplots(1)
+results.plot_x_t(ax)
+
+fig, ax = plt.subplots(1)
+results.raster_plot(ax,s=80)
 
 for x_AP,t_AP in zip(x_APs,t_APs):
-    plt.scatter(t_AP,x_AP)
+    ax.scatter(t_AP,x_AP)
     x_start,t_start = results.get_start_AP(x_AP,t_AP)
     x_max,t_xmax = results.get_xmax_AP(x_AP,t_AP)
     x_min,t_xmin = results.get_xmin_AP(x_AP,t_AP)
-    plt.scatter(t_start,x_start,s=10,c = 'k')
-    plt.scatter(t_xmax,x_max,s=10,c = 'g')
-    plt.scatter(t_xmin,x_min,s=10,c = 'b')
+    ax.scatter(t_start,x_start,s=10,c = 'k')
+    ax.scatter(t_xmax,x_max,s=10,c = 'g')
+    ax.scatter(t_xmin,x_min,s=10,c = 'b')
 
 if results.detect_AP_collisions():
     x_coll,t_coll,_ = results.get_collision_pts()
-    plt.scatter(t_coll,x_coll,s=50,c = 'r')
+    ax.scatter(t_coll,x_coll,s=50,c = 'r')
 
-plt.xlabel('time (ms)')
-plt.ylabel(r'position along the axon($\mu m$)')
-plt.xlim(0,results['tstop'])
-plt.savefig('./unitary_tests/figures/524_E.png')
+ax.set_xlabel('time (ms)')
+ax.set_ylabel(r'position along the axon($\mu m$)')
+ax.set_xlim(0,results['tstop'])
+fig.savefig('./unitary_tests/figures/524_E.png')
 
 d = 0.5
 L = 2000
@@ -222,27 +236,29 @@
 if (results.count_APs()):
     print(f"AP propagation velocity: {results.getAPspeed()[0]}m/s")
 
-plt.figure()
-plt.scatter(results['V_mem_raster_time'],results['V_mem_raster_x_position'],s=80)
+fig, ax = plt.subplots(1)
+results.plot_x_t(ax)
+
+fig, ax = plt.subplots(1)
+results.raster_plot(ax,s=80)
 
 for x_AP,t_AP in zip(x_APs,t_APs):
-    plt.scatter(t_AP,x_AP)
+    ax.scatter(t_AP,x_AP)
     x_start,t_start = results.get_start_AP(x_AP,t_AP)
     x_max,t_xmax = results.get_xmax_AP(x_AP,t_AP)
     x_min,t_xmin = results.get_xmin_AP(x_AP,t_AP)
-    plt.scatter(t_start,x_start,s=10,c = 'k')
-    plt.scatter(t_xmax,x_max,s=10,c = 'g')
-    plt.scatter(t_xmin,x_min,s=10,c = 'b')
+    ax.scatter(t_start,x_start,s=10,c = 'k')
+    ax.scatter(t_xmax,x_max,s=10,c = 'g')
+    ax.scatter(t_xmin,x_min,s=10,c = 'b')
 
 if results.detect_AP_collisions():
     x_coll,t_coll,_ = results.get_collision_pts()
-    plt.scatter(t_coll,x_coll,s=50,c = 'r')
-
-plt.xlabel('time (ms)')
-plt.ylabel(r'position along the axon($\mu m$)')
-plt.xlim(0,results['tstop'])
-plt.savefig('./unitary_tests/figures/524_F.png')
+    ax.scatter(t_coll,x_coll,s=50,c = 'r')
 
+ax.set_xlabel('time (ms)')
+ax.set_ylabel(r'position along the axon($\mu m$)')
+ax.set_xlim(0,results['tstop'])
+fig.savefig('./unitary_tests/figures/524_F.png')
 
 #No collision
 axon1 = nrv.unmyelinated(y,z,d,L,dt=0.005,rec='all')
@@ -264,26 +280,29 @@
 if (results.count_APs()):
     print(f"AP propagation velocity: {results.getAPspeed()[0]}m/s")
 
-plt.figure()
-plt.scatter(results['V_mem_raster_time'],results['V_mem_raster_x_position'],s=80)
+fig, ax = plt.subplots(1)
+results.plot_x_t(ax)
+
+fig, ax = plt.subplots(1)
+results.raster_plot(ax,s=80)
 
 for x_AP,t_AP in zip(x_APs,t_APs):
-    plt.scatter(t_AP,x_AP)
+    ax.scatter(t_AP,x_AP)
     x_start,t_start = results.get_start_AP(x_AP,t_AP)
     x_max,t_xmax = results.get_xmax_AP(x_AP,t_AP)
     x_min,t_xmin = results.get_xmin_AP(x_AP,t_AP)
-    plt.scatter(t_start,x_start,s=10,c = 'k')
-    plt.scatter(t_xmax,x_max,s=10,c = 'g')
-    plt.scatter(t_xmin,x_min,s=10,c = 'b')
+    ax.scatter(t_start,x_start,s=10,c = 'k')
+    ax.scatter(t_xmax,x_max,s=10,c = 'g')
+    ax.scatter(t_xmin,x_min,s=10,c = 'b')
 
 if results.detect_AP_collisions():
     x_coll,t_coll,_ = results.get_collision_pts()
-    plt.scatter(t_coll,x_coll,s=50,c = 'r')
+    ax.scatter(t_coll,x_coll,s=50,c = 'r')
 
-plt.xlabel('time (ms)')
-plt.ylabel(r'position along the axon($\mu m$)')
-plt.xlim(0,results['tstop'])
-plt.savefig('./unitary_tests/figures/524_G.png')
+ax.set_xlabel('time (ms)')
+ax.set_ylabel(r'position along the axon($\mu m$)')
+ax.set_xlim(0,results['tstop'])
+fig.savefig('./unitary_tests/figures/524_G.png')
 
 
 #with AP collision
@@ -306,26 +325,30 @@
 if (results.count_APs()):
     print(f"AP propagation velocity: {results.getAPspeed()[0]}m/s")
 
-plt.figure()
-plt.scatter(results['V_mem_raster_time'],results['V_mem_raster_x_position'],s=80)
+fig, ax = plt.subplots(1)
+results.plot_x_t(ax)
+
+fig, ax = plt.subplots(1)
+results.raster_plot(ax,s=80)
 
 for x_AP,t_AP in zip(x_APs,t_APs):
-    plt.scatter(t_AP,x_AP)
+    ax.scatter(t_AP,x_AP)
     x_start,t_start = results.get_start_AP(x_AP,t_AP)
     x_max,t_xmax = results.get_xmax_AP(x_AP,t_AP)
     x_min,t_xmin = results.get_xmin_AP(x_AP,t_AP)
-    plt.scatter(t_start,x_start,s=10,c = 'k')
-    plt.scatter(t_xmax,x_max,s=10,c = 'g')
-    plt.scatter(t_xmin,x_min,s=10,c = 'b')
+    ax.scatter(t_start,x_start,s=10,c = 'k')
+    ax.scatter(t_xmax,x_max,s=10,c = 'g')
+    ax.scatter(t_xmin,x_min,s=10,c = 'b')
 
 if results.detect_AP_collisions():
     x_coll,t_coll,_ = results.get_collision_pts()
-    plt.scatter(t_coll,x_coll,s=50,c = 'r')
+    ax.scatter(t_coll,x_coll,s=50,c = 'r')
+
+ax.set_xlabel('time (ms)')
+ax.set_ylabel(r'position along the axon($\mu m$)')
+ax.set_xlim(0,results['tstop'])
+fig.savefig('./unitary_tests/figures/524_H.png')
 
-plt.xlabel('time (ms)')
-plt.ylabel(r'position along the axon($\mu m$)')
-plt.xlim(0,results['tstop'])
-plt.savefig('./unitary_tests/figures/524_H.png')
 
 axon3 = nrv.unmyelinated(y,z,d,L,dt=0.005,rec='all')
 t_start = 2
@@ -343,26 +366,29 @@
 if (results.count_APs()):
     print(f"AP propagation velocity: {results.getAPspeed()[0]}m/s")
 
-plt.figure()
-plt.scatter(results['V_mem_raster_time'],results['V_mem_raster_x_position'],s=80)
+fig, ax = plt.subplots(1)
+results.plot_x_t(ax)
+
+fig, ax = plt.subplots(1)
+results.raster_plot(ax,s=80)
 
 for x_AP,t_AP in zip(x_APs,t_APs):
-    plt.scatter(t_AP,x_AP)
+    ax.scatter(t_AP,x_AP)
     x_start,t_start = results.get_start_AP(x_AP,t_AP)
     x_max,t_xmax = results.get_xmax_AP(x_AP,t_AP)
     x_min,t_xmin = results.get_xmin_AP(x_AP,t_AP)
-    plt.scatter(t_start,x_start,s=10,c = 'k')
-    plt.scatter(t_xmax,x_max,s=10,c = 'g')
-    plt.scatter(t_xmin,x_min,s=10,c = 'b')
+    ax.scatter(t_start,x_start,s=10,c = 'k')
+    ax.scatter(t_xmax,x_max,s=10,c = 'g')
+    ax.scatter(t_xmin,x_min,s=10,c = 'b')
 
 if results.detect_AP_collisions():
     x_coll,t_coll,_ = results.get_collision_pts()
-    plt.scatter(t_coll,x_coll,s=50,c = 'r')
+    ax.scatter(t_coll,x_coll,s=50,c = 'r')
 
-plt.xlabel('time (ms)')
-plt.ylabel(r'position along the axon($\mu m$)')
-plt.xlim(0,results['tstop'])
-plt.savefig('./unitary_tests/figures/524_I.png')
+ax.set_xlabel('time (ms)')
+ax.set_ylabel(r'position along the axon($\mu m$)')
+ax.set_xlim(0,results['tstop'])
+fig.savefig('./unitary_tests/figures/524_I.png')
 
 
 axon4 = nrv.unmyelinated(y,z,d,L,dt=0.005,rec='all')
@@ -380,26 +406,30 @@
 if (results.count_APs()):
     print(f"AP propagation velocity: {results.getAPspeed()[0]}m/s")
 
-plt.figure()
-plt.scatter(results['V_mem_raster_time'],results['V_mem_raster_x_position'],s=80)
+fig, ax = plt.subplots(1)
+results.plot_x_t(ax)
+
+fig, ax = plt.subplots(1)
+results.raster_plot(ax,s=80)
 
 for x_AP,t_AP in zip(x_APs,t_APs):
-    plt.scatter(t_AP,x_AP)
+    ax.scatter(t_AP,x_AP)
     x_start,t_start = results.get_start_AP(x_AP,t_AP)
     x_max,t_xmax = results.get_xmax_AP(x_AP,t_AP)
     x_min,t_xmin = results.get_xmin_AP(x_AP,t_AP)
-    plt.scatter(t_start,x_start,s=10,c = 'k')
-    plt.scatter(t_xmax,x_max,s=10,c = 'g')
-    plt.scatter(t_xmin,x_min,s=10,c = 'b')
+    ax.scatter(t_start,x_start,s=10,c = 'k')
+    ax.scatter(t_xmax,x_max,s=10,c = 'g')
+    ax.scatter(t_xmin,x_min,s=10,c = 'b')
 
 if results.detect_AP_collisions():
     x_coll,t_coll,_ = results.get_collision_pts()
-    plt.scatter(t_coll,x_coll,s=50,c = 'r')
+    ax.scatter(t_coll,x_coll,s=50,c = 'r')
+
+ax.set_xlabel('time (ms)')
+ax.set_ylabel(r'position along the axon($\mu m$)')
+ax.set_xlim(0,results['tstop'])
+fig.savefig('./unitary_tests/figures/524_J.png')
 
-plt.xlabel('time (ms)')
-plt.ylabel(r'position along the axon($\mu m$)')
-plt.xlim(0,results['tstop'])
-plt.savefig('./unitary_tests/figures/524_J.png')
 
 
-#plt.show()
+#plt.show()
\ No newline at end of file
diff --git a/tests/unitary_tests/531_test_colormap_plot.py b/tests/unitary_tests/531_test_colormap_plot.py
index 4908f257..919aea5a 100644
--- a/tests/unitary_tests/531_test_colormap_plot.py
+++ b/tests/unitary_tests/531_test_colormap_plot.py
@@ -2,14 +2,14 @@
 import matplotlib.pyplot as plt
 
 # Generating full results
-ax = nrv.myelinated(L=21000, rec='All')
+ax = nrv.myelinated(L=21000, rec='all')
 ax.insert_I_Clamp(0, 0, 0.1, 2)
 res = ax(t_sim=5)
-
+del ax
 ax2 = nrv.unmyelinated(L=2000)
 ax2.insert_I_Clamp(0, 0, 0.1, 2)
 res2 = ax2(t_sim=5)
-
+del ax2
 
 fig, axs = plt.subplots(2, 1)
 res.colormap_plot(axs[0], "V_mem")
diff --git a/tests/unitary_tests/533_test_raster_find_peaks.py b/tests/unitary_tests/533_test_raster_find_peaks.py
new file mode 100644
index 00000000..70b77904
--- /dev/null
+++ b/tests/unitary_tests/533_test_raster_find_peaks.py
@@ -0,0 +1,47 @@
+import nrv 
+from scipy.signal import find_peaks
+import matplotlib.pyplot as plt
+import numpy as np
+
+y = 0
+z = 0
+d = 10
+L = 20000
+
+########## test A : myelinated record all #############
+axon1 = nrv.myelinated(y,z,d,L,dt=0.005,rec='all')
+
+t_start = 2
+duration = 0.1
+amplitude = 2
+axon1.insert_I_Clamp(0.5, t_start, duration, amplitude)
+axon1.insert_I_Clamp(0.5, t_start+0.5, duration, amplitude)
+#axon1.insert_I_Clamp(0.5, t_start+1.0, duration, amplitude)
+axon1.insert_I_Clamp(0.5, t_start+2.5, duration, amplitude)
+axon1.insert_I_Clamp(0.5, t_start+5.5, duration, amplitude)
+
+results = axon1.simulate(t_sim=8)
+x = results["t"]
+y = results["V_mem"][0]
+height = [0,70]
+
+t_refractory = 0.5
+dt = x[1]-x[0]
+dis = int(t_refractory/dt)
+
+t_min_AP=0.1
+width = int(t_min_AP/dt)
+peaks, _ = find_peaks(y, height=height,distance=dis, width=width)
+
+
+
+fig, ax = plt.subplots(1)
+results.plot_x_t(ax)
+fig.savefig('./unitary_tests/figures/533_peaks_A.png')
+
+results.rasterize()
+fig, ax = plt.subplots(1)
+results.raster_plot(ax)
+fig.savefig('./unitary_tests/figures/533_peaks_B.png')
+
+#plt.show()
\ No newline at end of file
diff --git a/tests/unitary_tests/900_test_general_config.py b/tests/unitary_tests/900_test_general_config.py
new file mode 100644
index 00000000..19494785
--- /dev/null
+++ b/tests/unitary_tests/900_test_general_config.py
@@ -0,0 +1,4 @@
+import nrv
+
+nrv.CONFIG.display_machine_config()
+print('done')
\ No newline at end of file
diff --git a/tests/unitary_tests/sources/26_test_svg.json b/tests/unitary_tests/sources/26_test_svg.json
index 123bb47d..f019edaa 100644
--- a/tests/unitary_tests/sources/26_test_svg.json
+++ b/tests/unitary_tests/sources/26_test_svg.json
@@ -1,1 +1,1 @@
-{"__NRVObject__": true, "nrv_type": "unmyelinated_results", "np_keys": {"x": "float64", "x_rec": "float64", "t": "float64", "V_mem": "float64"}, "t_sim": 1, "record_V_mem": true, "record_I_mem": false, "record_I_ions": false, "record_particles": false, "record_g_mem": false, "record_g_ions": false, "loaded_footprints": null, "dt": 0.01, "type": "axon", "x": [0.0, 8.333333333333332, 25.0, 41.66666666666667, 50.0], "y": 0, "z": 0, "d": 1, "L": 50, "Nseg_per_sec": 0, "freq": 100, "freq_min": 0, "mesh_shape": "plateau_sigmoid", "alpha_max": 0.3, "d_lambda": 0.1, "v_init": -70, "T": 37, "threshold": -40, "model": "Rattay_Aberham", "sim_time": 0.00037217140197753906, "timeVector": null, "t_len": 0, "created": false, "Nsec": 1, "Nseg": 3, "myelinated": false, "x_rec": [0.0, 8.333333333333332, 25.0, 41.66666666666667, 50.0], "rec": "all", "node_index": null, "Nrec": 5, "rec_position_list": [[0.0, 0.16666666666666666, 0.5, 0.8333333333333334, 1]], "result_type": "unmyelinated", "diameter": 1, "tstop": 1, "intra_stim_positions": [], "intra_stim_starts": [], "intra_stim_durations": [], "intra_stim_amplitudes": [], "Simulation_state": "Successful", "t": [0.0, 0.01, 0.02, 0.030000000000000002, 0.04, 0.049999999999999996, 0.05999999999999999, 0.06999999999999999, 0.08, 0.09000000000000001, 0.10000000000000002, 0.11000000000000003, 0.12000000000000004, 0.13000000000000003, 0.14000000000000004, 0.15000000000000005, 0.16000000000000006, 0.17000000000000007, 0.18000000000000008, 0.19000000000000009, 0.2000000000000001, 0.2100000000000001, 0.2200000000000001, 0.23000000000000012, 0.24000000000000013, 0.2500000000000001, 0.2600000000000001, 0.27000000000000013, 0.28000000000000014, 0.29000000000000015, 0.30000000000000016, 0.31000000000000016, 0.3200000000000002, 0.3300000000000002, 0.3400000000000002, 0.3500000000000002, 0.3600000000000002, 0.3700000000000002, 0.3800000000000002, 0.39000000000000024, 0.40000000000000024, 0.41000000000000025, 0.42000000000000026, 0.43000000000000027, 0.4400000000000003, 0.4500000000000003, 0.4600000000000003, 0.4700000000000003, 0.4800000000000003, 0.4900000000000003, 0.5000000000000003, 0.5100000000000003, 0.5200000000000004, 0.5300000000000004, 0.5400000000000004, 0.5500000000000004, 0.5600000000000004, 0.5700000000000004, 0.5800000000000004, 0.5900000000000004, 0.6000000000000004, 0.6100000000000004, 0.6200000000000004, 0.6300000000000004, 0.6400000000000005, 0.6500000000000005, 0.6600000000000005, 0.6700000000000005, 0.6800000000000005, 0.6900000000000005, 0.7000000000000005, 0.7100000000000005, 0.7200000000000005, 0.7300000000000005, 0.7400000000000005, 0.7500000000000006, 0.7600000000000006, 0.7700000000000006, 0.7800000000000006, 0.7900000000000006, 0.8000000000000006, 0.8100000000000006, 0.8200000000000006, 0.8300000000000006, 0.8400000000000006, 0.8500000000000006, 0.8600000000000007, 0.8700000000000007, 0.8800000000000007, 0.8900000000000007, 0.9000000000000007, 0.9100000000000007, 0.9200000000000007, 0.9300000000000007, 0.9400000000000007, 0.9500000000000007, 0.9600000000000007, 0.9700000000000008, 0.9800000000000008, 0.9900000000000008, 1.0000000000000007], "V_mem": [[-70.0, -69.99999681630679, -69.99999368007855, -69.9999905877947, -69.99998753737349, -69.99998452758797, -69.9999815577162, -69.9999786273316, -69.9999757361776, -69.99997288409264, -69.99997007096547, -69.99996729670855, -69.99996456124231, -69.99996186448598, -69.99995920635229, -69.99995658674445, -69.99995400555459, -69.99995146266302, -69.999948957938, -69.99994649123575, -69.99994406240064, -69.99994167126559, -69.9999393176523, -69.99993700137179, -69.9999347222247, -69.99993248000172, -69.99993027448407, -69.99992810544383, -69.99992597264435, -69.99992387584066, -69.99992181477988, -69.99991978920151, -69.9999177988379, -69.99991584341451, -69.99991392265034, -69.9999120362582, -69.99991018394509, -69.99990836541251, -69.99990658035678, -69.99990482846931, -69.99990310943697, -69.99990142294232, -69.99989976866388, -69.9998981462765, -69.9998965554515, -69.99989499585706, -69.99989346715837, -69.99989196901794, -69.99989050109578, -69.99988906304971, -69.99988765453553, -69.99988627520725, -69.9998849247173, -69.99988360271679, -69.9998823088556, -69.9998810427827, -69.99987980414623, -69.99987859259376, -69.99987740777243, -69.99987624932912, -69.99987511691063, -69.99987401016384, -69.99987292873584, -69.99987187227411, -69.99987084042667, -69.99986983284215, -69.99986884917004, -69.99986788906071, -69.99986695216559, -69.9998660381373, -69.99986514662972, -69.99986427729814, -69.99986342979938, -69.99986260379183, -69.9998617989356, -69.9998610148926, -69.99986025132665, -69.99985950790355, -69.99985878429113, -69.9998580801594, -69.99985739518057, -69.99985672902915, -69.99985608138199, -69.9998554519184, -69.99985484032017, -69.99985424627161, -69.99985366945965, -69.9998531095739, -69.99985256630666, -69.99985203935297, -69.99985152841072, -69.99985103318056, -69.9998505533661, -69.99985008867384, -69.99984963881322, -69.99984920349667, -69.99984878243964, -69.99984837536063, -69.99984798198116, -69.9998476020259, -69.99984723522257], [-70.0, -69.99999681630679, -69.99999368007855, -69.9999905877947, -69.99998753737349, -69.99998452758797, -69.9999815577162, -69.9999786273316, -69.9999757361776, -69.99997288409264, -69.99997007096547, -69.99996729670855, -69.99996456124231, -69.99996186448598, -69.99995920635229, -69.99995658674445, -69.99995400555459, -69.99995146266302, -69.999948957938, -69.99994649123575, -69.99994406240064, -69.99994167126559, -69.9999393176523, -69.99993700137179, -69.9999347222247, -69.99993248000172, -69.99993027448407, -69.99992810544383, -69.99992597264435, -69.99992387584066, -69.99992181477988, -69.99991978920151, -69.9999177988379, -69.99991584341451, -69.99991392265034, -69.9999120362582, -69.99991018394509, -69.99990836541251, -69.99990658035678, -69.99990482846931, -69.99990310943697, -69.99990142294232, -69.99989976866388, -69.9998981462765, -69.9998965554515, -69.99989499585706, -69.99989346715837, -69.99989196901794, -69.99989050109578, -69.99988906304971, -69.99988765453553, -69.99988627520725, -69.9998849247173, -69.99988360271679, -69.9998823088556, -69.9998810427827, -69.99987980414623, -69.99987859259376, -69.99987740777243, -69.99987624932912, -69.99987511691063, -69.99987401016384, -69.99987292873584, -69.99987187227411, -69.99987084042667, -69.99986983284215, -69.99986884917004, -69.99986788906071, -69.99986695216559, -69.9998660381373, -69.99986514662972, -69.99986427729814, -69.99986342979938, -69.99986260379183, -69.9998617989356, -69.9998610148926, -69.99986025132665, -69.99985950790355, -69.99985878429113, -69.9998580801594, -69.99985739518057, -69.99985672902915, -69.99985608138199, -69.9998554519184, -69.99985484032017, -69.99985424627161, -69.99985366945965, -69.9998531095739, -69.99985256630666, -69.99985203935297, -69.99985152841072, -69.99985103318056, -69.9998505533661, -69.99985008867384, -69.99984963881322, -69.99984920349667, -69.99984878243964, -69.99984837536063, -69.99984798198116, -69.9998476020259, -69.99984723522257], [-70.0, -69.99999681630679, -69.99999368007855, -69.9999905877947, -69.99998753737349, -69.99998452758797, -69.9999815577162, -69.9999786273316, -69.9999757361776, -69.99997288409264, -69.99997007096547, -69.99996729670855, -69.99996456124231, -69.99996186448598, -69.99995920635229, -69.99995658674445, -69.99995400555459, -69.99995146266302, -69.999948957938, -69.99994649123575, -69.99994406240064, -69.99994167126559, -69.9999393176523, -69.99993700137179, -69.9999347222247, -69.99993248000172, -69.99993027448407, -69.99992810544383, -69.99992597264435, -69.99992387584066, -69.99992181477988, -69.99991978920151, -69.9999177988379, -69.99991584341451, -69.99991392265034, -69.9999120362582, -69.99991018394509, -69.99990836541251, -69.99990658035678, -69.99990482846931, -69.99990310943697, -69.99990142294232, -69.99989976866388, -69.9998981462765, -69.9998965554515, -69.99989499585706, -69.99989346715837, -69.99989196901794, -69.99989050109578, -69.99988906304971, -69.99988765453553, -69.99988627520725, -69.9998849247173, -69.99988360271679, -69.9998823088556, -69.9998810427827, -69.99987980414623, -69.99987859259376, -69.99987740777243, -69.99987624932912, -69.99987511691063, -69.99987401016384, -69.99987292873584, -69.99987187227411, -69.99987084042667, -69.99986983284215, -69.99986884917004, -69.99986788906071, -69.99986695216559, -69.9998660381373, -69.99986514662972, -69.99986427729814, -69.99986342979938, -69.99986260379183, -69.9998617989356, -69.9998610148926, -69.99986025132665, -69.99985950790355, -69.99985878429113, -69.9998580801594, -69.99985739518057, -69.99985672902915, -69.99985608138199, -69.9998554519184, -69.99985484032017, -69.99985424627161, -69.99985366945965, -69.9998531095739, -69.99985256630666, -69.99985203935297, -69.99985152841072, -69.99985103318056, -69.9998505533661, -69.99985008867384, -69.99984963881322, -69.99984920349667, -69.99984878243964, -69.99984837536063, -69.99984798198116, -69.9998476020259, -69.99984723522257], [-70.0, -69.99999681630679, -69.99999368007855, -69.9999905877947, -69.99998753737349, -69.99998452758797, -69.9999815577162, -69.9999786273316, -69.9999757361776, -69.99997288409264, -69.99997007096547, -69.99996729670855, -69.99996456124231, -69.99996186448598, -69.99995920635229, -69.99995658674445, -69.99995400555459, -69.99995146266302, -69.999948957938, -69.99994649123575, -69.99994406240064, -69.99994167126559, -69.9999393176523, -69.99993700137179, -69.9999347222247, -69.99993248000172, -69.99993027448407, -69.99992810544383, -69.99992597264435, -69.99992387584066, -69.99992181477988, -69.99991978920151, -69.9999177988379, -69.99991584341451, -69.99991392265034, -69.9999120362582, -69.99991018394509, -69.99990836541251, -69.99990658035678, -69.99990482846931, -69.99990310943697, -69.99990142294232, -69.99989976866388, -69.9998981462765, -69.9998965554515, -69.99989499585706, -69.99989346715837, -69.99989196901794, -69.99989050109578, -69.99988906304971, -69.99988765453553, -69.99988627520725, -69.9998849247173, -69.99988360271679, -69.9998823088556, -69.9998810427827, -69.99987980414623, -69.99987859259376, -69.99987740777243, -69.99987624932912, -69.99987511691063, -69.99987401016384, -69.99987292873584, -69.99987187227411, -69.99987084042667, -69.99986983284215, -69.99986884917004, -69.99986788906071, -69.99986695216559, -69.9998660381373, -69.99986514662972, -69.99986427729814, -69.99986342979938, -69.99986260379183, -69.9998617989356, -69.9998610148926, -69.99986025132665, -69.99985950790355, -69.99985878429113, -69.9998580801594, -69.99985739518057, -69.99985672902915, -69.99985608138199, -69.9998554519184, -69.99985484032017, -69.99985424627161, -69.99985366945965, -69.9998531095739, -69.99985256630666, -69.99985203935297, -69.99985152841072, -69.99985103318056, -69.9998505533661, -69.99985008867384, -69.99984963881322, -69.99984920349667, -69.99984878243964, -69.99984837536063, -69.99984798198116, -69.9998476020259, -69.99984723522257], [-70.0, -69.99999681630679, -69.99999368007855, -69.9999905877947, -69.99998753737349, -69.99998452758797, -69.9999815577162, -69.9999786273316, -69.9999757361776, -69.99997288409264, -69.99997007096547, -69.99996729670855, -69.99996456124231, -69.99996186448598, -69.99995920635229, -69.99995658674445, -69.99995400555459, -69.99995146266302, -69.999948957938, -69.99994649123575, -69.99994406240064, -69.99994167126559, -69.9999393176523, -69.99993700137179, -69.9999347222247, -69.99993248000172, -69.99993027448407, -69.99992810544383, -69.99992597264435, -69.99992387584066, -69.99992181477988, -69.99991978920151, -69.9999177988379, -69.99991584341451, -69.99991392265034, -69.9999120362582, -69.99991018394509, -69.99990836541251, -69.99990658035678, -69.99990482846931, -69.99990310943697, -69.99990142294232, -69.99989976866388, -69.9998981462765, -69.9998965554515, -69.99989499585706, -69.99989346715837, -69.99989196901794, -69.99989050109578, -69.99988906304971, -69.99988765453553, -69.99988627520725, -69.9998849247173, -69.99988360271679, -69.9998823088556, -69.9998810427827, -69.99987980414623, -69.99987859259376, -69.99987740777243, -69.99987624932912, -69.99987511691063, -69.99987401016384, -69.99987292873584, -69.99987187227411, -69.99987084042667, -69.99986983284215, -69.99986884917004, -69.99986788906071, -69.99986695216559, -69.9998660381373, -69.99986514662972, -69.99986427729814, -69.99986342979938, -69.99986260379183, -69.9998617989356, -69.9998610148926, -69.99986025132665, -69.99985950790355, -69.99985878429113, -69.9998580801594, -69.99985739518057, -69.99985672902915, -69.99985608138199, -69.9998554519184, -69.99985484032017, -69.99985424627161, -69.99985366945965, -69.9998531095739, -69.99985256630666, -69.99985203935297, -69.99985152841072, -69.99985103318056, -69.9998505533661, -69.99985008867384, -69.99984963881322, -69.99984920349667, -69.99984878243964, -69.99984837536063, -69.99984798198116, -69.9998476020259, -69.99984723522257]]}
\ No newline at end of file
+{"__NRVObject__": true, "nrv_type": "unmyelinated_results", "np_keys": {"x": "float64", "x_rec": "float64", "t": "float64", "V_mem": "float64"}, "t_sim": 1, "record_V_mem": true, "record_I_mem": false, "record_I_ions": false, "record_particles": false, "record_g_mem": false, "record_g_ions": false, "loaded_footprints": null, "dt": 0.01, "type": "axon", "x": [0.0, 8.333333333333332, 25.0, 41.66666666666667, 50.0], "y": 0, "z": 0, "d": 1, "L": 50, "Nseg_per_sec": 0, "freq": 100, "freq_min": 0, "mesh_shape": "plateau_sigmoid", "alpha_max": 0.3, "d_lambda": 0.1, "v_init": -70, "T": 37, "threshold": -40, "model": "Rattay_Aberham", "sim_time": 0.00021123886108398438, "timeVector": null, "t_len": 0, "created": false, "Nsec": 1, "Nseg": 3, "myelinated": false, "x_rec": [0.0, 8.333333333333332, 25.0, 41.66666666666667, 50.0], "rec": "all", "node_index": null, "Nrec": 5, "rec_position_list": [[0.0, 0.16666666666666666, 0.5, 0.8333333333333334, 1]], "result_type": "unmyelinated", "diameter": 1, "tstop": 1, "intra_stim_positions": [], "intra_stim_starts": [], "intra_stim_durations": [], "intra_stim_amplitudes": [], "Simulation_state": "Successful", "t": [0.0, 0.01, 0.02, 0.030000000000000002, 0.04, 0.049999999999999996, 0.05999999999999999, 0.06999999999999999, 0.08, 0.09000000000000001, 0.10000000000000002, 0.11000000000000003, 0.12000000000000004, 0.13000000000000003, 0.14000000000000004, 0.15000000000000005, 0.16000000000000006, 0.17000000000000007, 0.18000000000000008, 0.19000000000000009, 0.2000000000000001, 0.2100000000000001, 0.2200000000000001, 0.23000000000000012, 0.24000000000000013, 0.2500000000000001, 0.2600000000000001, 0.27000000000000013, 0.28000000000000014, 0.29000000000000015, 0.30000000000000016, 0.31000000000000016, 0.3200000000000002, 0.3300000000000002, 0.3400000000000002, 0.3500000000000002, 0.3600000000000002, 0.3700000000000002, 0.3800000000000002, 0.39000000000000024, 0.40000000000000024, 0.41000000000000025, 0.42000000000000026, 0.43000000000000027, 0.4400000000000003, 0.4500000000000003, 0.4600000000000003, 0.4700000000000003, 0.4800000000000003, 0.4900000000000003, 0.5000000000000003, 0.5100000000000003, 0.5200000000000004, 0.5300000000000004, 0.5400000000000004, 0.5500000000000004, 0.5600000000000004, 0.5700000000000004, 0.5800000000000004, 0.5900000000000004, 0.6000000000000004, 0.6100000000000004, 0.6200000000000004, 0.6300000000000004, 0.6400000000000005, 0.6500000000000005, 0.6600000000000005, 0.6700000000000005, 0.6800000000000005, 0.6900000000000005, 0.7000000000000005, 0.7100000000000005, 0.7200000000000005, 0.7300000000000005, 0.7400000000000005, 0.7500000000000006, 0.7600000000000006, 0.7700000000000006, 0.7800000000000006, 0.7900000000000006, 0.8000000000000006, 0.8100000000000006, 0.8200000000000006, 0.8300000000000006, 0.8400000000000006, 0.8500000000000006, 0.8600000000000007, 0.8700000000000007, 0.8800000000000007, 0.8900000000000007, 0.9000000000000007, 0.9100000000000007, 0.9200000000000007, 0.9300000000000007, 0.9400000000000007, 0.9500000000000007, 0.9600000000000007, 0.9700000000000008, 0.9800000000000008, 0.9900000000000008, 1.0000000000000007], "V_mem": [[-70.0, -69.99999681630679, -69.99999368007855, -69.9999905877947, -69.99998753737349, -69.99998452758797, -69.9999815577162, -69.9999786273316, -69.9999757361776, -69.99997288409264, -69.99997007096547, -69.99996729670855, -69.99996456124231, -69.99996186448598, -69.99995920635229, -69.99995658674445, -69.99995400555459, -69.99995146266302, -69.999948957938, -69.99994649123575, -69.99994406240064, -69.99994167126559, -69.9999393176523, -69.99993700137179, -69.9999347222247, -69.99993248000172, -69.99993027448407, -69.99992810544383, -69.99992597264435, -69.99992387584066, -69.99992181477988, -69.99991978920151, -69.9999177988379, -69.99991584341451, -69.99991392265034, -69.9999120362582, -69.99991018394509, -69.99990836541251, -69.99990658035678, -69.99990482846931, -69.99990310943697, -69.99990142294232, -69.99989976866388, -69.9998981462765, -69.9998965554515, -69.99989499585706, -69.99989346715837, -69.99989196901794, -69.99989050109578, -69.99988906304971, -69.99988765453553, -69.99988627520725, -69.9998849247173, -69.99988360271679, -69.9998823088556, -69.9998810427827, -69.99987980414623, -69.99987859259376, -69.99987740777243, -69.99987624932912, -69.99987511691063, -69.99987401016384, -69.99987292873584, -69.99987187227411, -69.99987084042667, -69.99986983284215, -69.99986884917004, -69.99986788906071, -69.99986695216559, -69.9998660381373, -69.99986514662972, -69.99986427729814, -69.99986342979938, -69.99986260379183, -69.9998617989356, -69.9998610148926, -69.99986025132665, -69.99985950790355, -69.99985878429113, -69.9998580801594, -69.99985739518057, -69.99985672902915, -69.99985608138199, -69.9998554519184, -69.99985484032017, -69.99985424627161, -69.99985366945965, -69.9998531095739, -69.99985256630666, -69.99985203935297, -69.99985152841072, -69.99985103318056, -69.9998505533661, -69.99985008867384, -69.99984963881322, -69.99984920349667, -69.99984878243964, -69.99984837536063, -69.99984798198116, -69.9998476020259, -69.99984723522257], [-70.0, -69.99999681630679, -69.99999368007855, -69.9999905877947, -69.99998753737349, -69.99998452758797, -69.9999815577162, -69.9999786273316, -69.9999757361776, -69.99997288409264, -69.99997007096547, -69.99996729670855, -69.99996456124231, -69.99996186448598, -69.99995920635229, -69.99995658674445, -69.99995400555459, -69.99995146266302, -69.999948957938, -69.99994649123575, -69.99994406240064, -69.99994167126559, -69.9999393176523, -69.99993700137179, -69.9999347222247, -69.99993248000172, -69.99993027448407, -69.99992810544383, -69.99992597264435, -69.99992387584066, -69.99992181477988, -69.99991978920151, -69.9999177988379, -69.99991584341451, -69.99991392265034, -69.9999120362582, -69.99991018394509, -69.99990836541251, -69.99990658035678, -69.99990482846931, -69.99990310943697, -69.99990142294232, -69.99989976866388, -69.9998981462765, -69.9998965554515, -69.99989499585706, -69.99989346715837, -69.99989196901794, -69.99989050109578, -69.99988906304971, -69.99988765453553, -69.99988627520725, -69.9998849247173, -69.99988360271679, -69.9998823088556, -69.9998810427827, -69.99987980414623, -69.99987859259376, -69.99987740777243, -69.99987624932912, -69.99987511691063, -69.99987401016384, -69.99987292873584, -69.99987187227411, -69.99987084042667, -69.99986983284215, -69.99986884917004, -69.99986788906071, -69.99986695216559, -69.9998660381373, -69.99986514662972, -69.99986427729814, -69.99986342979938, -69.99986260379183, -69.9998617989356, -69.9998610148926, -69.99986025132665, -69.99985950790355, -69.99985878429113, -69.9998580801594, -69.99985739518057, -69.99985672902915, -69.99985608138199, -69.9998554519184, -69.99985484032017, -69.99985424627161, -69.99985366945965, -69.9998531095739, -69.99985256630666, -69.99985203935297, -69.99985152841072, -69.99985103318056, -69.9998505533661, -69.99985008867384, -69.99984963881322, -69.99984920349667, -69.99984878243964, -69.99984837536063, -69.99984798198116, -69.9998476020259, -69.99984723522257], [-70.0, -69.99999681630679, -69.99999368007855, -69.9999905877947, -69.99998753737349, -69.99998452758797, -69.9999815577162, -69.9999786273316, -69.9999757361776, -69.99997288409264, -69.99997007096547, -69.99996729670855, -69.99996456124231, -69.99996186448598, -69.99995920635229, -69.99995658674445, -69.99995400555459, -69.99995146266302, -69.999948957938, -69.99994649123575, -69.99994406240064, -69.99994167126559, -69.9999393176523, -69.99993700137179, -69.9999347222247, -69.99993248000172, -69.99993027448407, -69.99992810544383, -69.99992597264435, -69.99992387584066, -69.99992181477988, -69.99991978920151, -69.9999177988379, -69.99991584341451, -69.99991392265034, -69.9999120362582, -69.99991018394509, -69.99990836541251, -69.99990658035678, -69.99990482846931, -69.99990310943697, -69.99990142294232, -69.99989976866388, -69.9998981462765, -69.9998965554515, -69.99989499585706, -69.99989346715837, -69.99989196901794, -69.99989050109578, -69.99988906304971, -69.99988765453553, -69.99988627520725, -69.9998849247173, -69.99988360271679, -69.9998823088556, -69.9998810427827, -69.99987980414623, -69.99987859259376, -69.99987740777243, -69.99987624932912, -69.99987511691063, -69.99987401016384, -69.99987292873584, -69.99987187227411, -69.99987084042667, -69.99986983284215, -69.99986884917004, -69.99986788906071, -69.99986695216559, -69.9998660381373, -69.99986514662972, -69.99986427729814, -69.99986342979938, -69.99986260379183, -69.9998617989356, -69.9998610148926, -69.99986025132665, -69.99985950790355, -69.99985878429113, -69.9998580801594, -69.99985739518057, -69.99985672902915, -69.99985608138199, -69.9998554519184, -69.99985484032017, -69.99985424627161, -69.99985366945965, -69.9998531095739, -69.99985256630666, -69.99985203935297, -69.99985152841072, -69.99985103318056, -69.9998505533661, -69.99985008867384, -69.99984963881322, -69.99984920349667, -69.99984878243964, -69.99984837536063, -69.99984798198116, -69.9998476020259, -69.99984723522257], [-70.0, -69.99999681630679, -69.99999368007855, -69.9999905877947, -69.99998753737349, -69.99998452758797, -69.9999815577162, -69.9999786273316, -69.9999757361776, -69.99997288409264, -69.99997007096547, -69.99996729670855, -69.99996456124231, -69.99996186448598, -69.99995920635229, -69.99995658674445, -69.99995400555459, -69.99995146266302, -69.999948957938, -69.99994649123575, -69.99994406240064, -69.99994167126559, -69.9999393176523, -69.99993700137179, -69.9999347222247, -69.99993248000172, -69.99993027448407, -69.99992810544383, -69.99992597264435, -69.99992387584066, -69.99992181477988, -69.99991978920151, -69.9999177988379, -69.99991584341451, -69.99991392265034, -69.9999120362582, -69.99991018394509, -69.99990836541251, -69.99990658035678, -69.99990482846931, -69.99990310943697, -69.99990142294232, -69.99989976866388, -69.9998981462765, -69.9998965554515, -69.99989499585706, -69.99989346715837, -69.99989196901794, -69.99989050109578, -69.99988906304971, -69.99988765453553, -69.99988627520725, -69.9998849247173, -69.99988360271679, -69.9998823088556, -69.9998810427827, -69.99987980414623, -69.99987859259376, -69.99987740777243, -69.99987624932912, -69.99987511691063, -69.99987401016384, -69.99987292873584, -69.99987187227411, -69.99987084042667, -69.99986983284215, -69.99986884917004, -69.99986788906071, -69.99986695216559, -69.9998660381373, -69.99986514662972, -69.99986427729814, -69.99986342979938, -69.99986260379183, -69.9998617989356, -69.9998610148926, -69.99986025132665, -69.99985950790355, -69.99985878429113, -69.9998580801594, -69.99985739518057, -69.99985672902915, -69.99985608138199, -69.9998554519184, -69.99985484032017, -69.99985424627161, -69.99985366945965, -69.9998531095739, -69.99985256630666, -69.99985203935297, -69.99985152841072, -69.99985103318056, -69.9998505533661, -69.99985008867384, -69.99984963881322, -69.99984920349667, -69.99984878243964, -69.99984837536063, -69.99984798198116, -69.9998476020259, -69.99984723522257], [-70.0, -69.99999681630679, -69.99999368007855, -69.9999905877947, -69.99998753737349, -69.99998452758797, -69.9999815577162, -69.9999786273316, -69.9999757361776, -69.99997288409264, -69.99997007096547, -69.99996729670855, -69.99996456124231, -69.99996186448598, -69.99995920635229, -69.99995658674445, -69.99995400555459, -69.99995146266302, -69.999948957938, -69.99994649123575, -69.99994406240064, -69.99994167126559, -69.9999393176523, -69.99993700137179, -69.9999347222247, -69.99993248000172, -69.99993027448407, -69.99992810544383, -69.99992597264435, -69.99992387584066, -69.99992181477988, -69.99991978920151, -69.9999177988379, -69.99991584341451, -69.99991392265034, -69.9999120362582, -69.99991018394509, -69.99990836541251, -69.99990658035678, -69.99990482846931, -69.99990310943697, -69.99990142294232, -69.99989976866388, -69.9998981462765, -69.9998965554515, -69.99989499585706, -69.99989346715837, -69.99989196901794, -69.99989050109578, -69.99988906304971, -69.99988765453553, -69.99988627520725, -69.9998849247173, -69.99988360271679, -69.9998823088556, -69.9998810427827, -69.99987980414623, -69.99987859259376, -69.99987740777243, -69.99987624932912, -69.99987511691063, -69.99987401016384, -69.99987292873584, -69.99987187227411, -69.99987084042667, -69.99986983284215, -69.99986884917004, -69.99986788906071, -69.99986695216559, -69.9998660381373, -69.99986514662972, -69.99986427729814, -69.99986342979938, -69.99986260379183, -69.9998617989356, -69.9998610148926, -69.99986025132665, -69.99985950790355, -69.99985878429113, -69.9998580801594, -69.99985739518057, -69.99985672902915, -69.99985608138199, -69.9998554519184, -69.99985484032017, -69.99985424627161, -69.99985366945965, -69.9998531095739, -69.99985256630666, -69.99985203935297, -69.99985152841072, -69.99985103318056, -69.9998505533661, -69.99985008867384, -69.99984963881322, -69.99984920349667, -69.99984878243964, -69.99984837536063, -69.99984798198116, -69.9998476020259, -69.99984723522257]]}
\ No newline at end of file