diff --git a/__COPYRIGHT__.txt b/README-COPYRIGHT.txt
similarity index 100%
rename from __COPYRIGHT__.txt
rename to README-COPYRIGHT.txt
diff --git a/__LICENCE_utf-8__.txt b/README-LICENCE-utf8.txt
similarity index 100%
rename from __LICENCE_utf-8__.txt
rename to README-LICENCE-utf8.txt
diff --git a/standalone/NutriMorph-4-NT.zip b/standalone/NutriMorph-4-NT.zip
new file mode 100644
index 0000000000000000000000000000000000000000..b53f969a74e3ffd25ddcbcf6ccc81e1eef219237
Binary files /dev/null and b/standalone/NutriMorph-4-NT.zip differ
diff --git a/standalone/README-REQUIREMENTS.txt b/standalone/README-REQUIREMENTS.txt
new file mode 100644
index 0000000000000000000000000000000000000000..cad6588be6ebb86b18fe7b67ba70ffc4a9743442
--- /dev/null
+++ b/standalone/README-REQUIREMENTS.txt
@@ -0,0 +1,39 @@
+# Requirements automatically generated by pigar.
+# https://github.com/damnever/pigar
+
+# brick/general/feedback.py: 38
+# brick/processing/plot.py: 39,40
+# nutrimorph.py: 52
+matplotlib == 3.1.2
+
+# brick/component/connection.py: 41
+# brick/component/extension.py: 41
+# brick/component/glial_cmp.py: 38
+# brick/component/soma.py: 42
+# brick/feature/features_ext.py: 32
+# brick/feature/features_soma.py: 32
+# brick/general/type.py: 34
+# brick/processing/dijkstra_1_to_n.py: 46
+# brick/processing/frangi3.py: 45
+# brick/processing/map_labeling.py: 34
+# brick/processing/plot.py: 41
+# nutrimorph.py: 53
+numpy == 1.18.1
+
+# brick/component/extension.py: 42,43,44
+# brick/component/soma.py: 44,45,46
+# brick/feature/features_ext.py: 33
+# brick/feature/features_soma.py: 33
+# brick/processing/plot.py: 42
+# nutrimorph.py: 54,55
+# parameters.py: 32
+scikit_image == 0.16.2
+
+# brick/feature/features_soma.py: 34
+scikit_learn == 0.22.1
+
+# brick/component/extension.py: 45
+# brick/component/soma.py: 43
+# brick/processing/dijkstra_1_to_n.py: 47
+# brick/processing/frangi3.py: 46
+scipy == 1.4.1
diff --git a/standalone/auto-py-to-exe.json b/standalone/auto-py-to-exe.json
deleted file mode 100644
index b606edd62933c47d97d09311df720d43ea72406c..0000000000000000000000000000000000000000
--- a/standalone/auto-py-to-exe.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
-    "command_data":{
-	    "onefile":false,
-		"console":true,
-		"additional_files":{
-		    "addFiles_lbb4d":{
-			    "source":"C:/Users/eric/Documents/code/python-to-exe/nutrimorph/main_prm.py",
-				"destination":"."
-			},
-			"addFiles_ouqe7j":{
-			    "source":"C:/Users/eric/Documents/code/python-to-exe/nutrimorph/frangi3-nt.so",
-				"destination":"."
-			}
-		}
-	},
-	"id_injectable":{
-	    "file":"C:/Users/eric/Documents/code/python-to-exe/nutrimorph/main.py",
-		"icon":"",
-		"output_location":"C:/Users/eric/Documents/code/python-to-exe/nutrimorph/standalone",
-		"VALUE--upx-dir":"",
-		"VALUE--log-level":"",
-		"VALUE-n":"",
-		"VALUE--add-binary":"",
-		"VALUE-p":"",
-		"COMMASPLIT--hidden-import":"",
-		"VALUE--additional-hooks-dir":"",
-		"VALUE--runtime-hook":"",
-		"COMMASPLIT--exclude-module":"",
-		"VALUE--key":"",
-		"VALUE--debug":"",
-		"VALUE--version-file":"",
-		"VALUE-m":"",
-		"VALUE-r":"",
-		"VALUE--osx-bundle-identifier":"",
-		"VALUE--runtime-tmpdir":"",
-		"extra_command_data":""
-	},
-	"switches":{
-	    "disable_recursion_limit":false,
-		"OPTION-a":false,
-		"OPTION--clean":false,
-		"OPTION-s":false,
-		"OPTION--noupx":false,
-		"OPTION--uac-admin":false,
-		"OPTION--uac-uiaccess":false,
-		"OPTION--win-private-assemblies":false,
-		"OPTION--win-no-prefer-redirects":false,
-		"OPTION--bootloader-ignore-signals":false
-	}
-}
diff --git a/standalone/generate-w-pyinstaller.py b/standalone/generate-w-pyinstaller.py
new file mode 100644
index 0000000000000000000000000000000000000000..343db6124f2703ebd2aa7b431937c41ab0075fb1
--- /dev/null
+++ b/standalone/generate-w-pyinstaller.py
@@ -0,0 +1,159 @@
+import glob as gb_
+import os as os_
+import os.path as ph_
+import shutil as sh_
+import subprocess as sp_
+import sys as sy_
+import zipfile as zp_
+from os import name as OS_NAME
+from os import pathsep as PATH_SEP
+from typing import Sequence, Union
+
+import pprint as pp_
+import PyInstaller.__main__
+
+
+PY_SCRIPT = "nutrimorph.py"
+PARAMETERS = "parameters.py"
+BRICK_FOLDER = "brick"
+RES_PATH_CMPS = ("data",)
+SRC_PATH_CMPS = ("..",)
+README_PREFIX = "README"
+RES_PREFIX = "DIO"
+
+DEP_LIST_DOC = f"{README_PREFIX}-REQUIREMENTS.txt"
+REQUIREMENTS_MARKER = "Requires:"
+
+DIST_ROOT_FOLDER = "__dist__"
+BUILD_ROOT_FOLDER = "__build__"
+PER_OS_DIST_FOLDER = f"NutriMorph-4-{OS_NAME.upper()}"
+DST_RES_FOLDER = "data"
+
+
+def InBaseFolder(path: Union[str, Sequence[str]]) -> str:
+    #
+    if isinstance(path, str):
+        return ph_.realpath(ph_.join(*SRC_PATH_CMPS, path))
+    else:
+        return ph_.realpath(ph_.join(*SRC_PATH_CMPS, *path))
+
+
+SCRIPT_NAME = ph_.splitext(PY_SCRIPT)[0]
+PER_OS_DIST_FOLDER_PATH = ph_.join(DIST_ROOT_FOLDER, PER_OS_DIST_FOLDER)
+PER_OS_and_SCRIPT_DIST_PATH = ph_.join(PER_OS_DIST_FOLDER_PATH, SCRIPT_NAME)
+PER_OS_BUILD_FOLDER_PATH = ph_.join(BUILD_ROOT_FOLDER, OS_NAME)
+
+PY_SCRIPT_PATH = InBaseFolder(PY_SCRIPT)
+PARAMETERS_PATH = InBaseFolder(PARAMETERS)
+BRICK_FOLDER_PATH = InBaseFolder(BRICK_FOLDER)
+RES_FOLDER_PATH = InBaseFolder(ph_.join(*RES_PATH_CMPS))
+
+FRANGI3_PREFIX = "frangi3"
+if OS_NAME == "nt":
+    # In Wine on Linux, realpath does not resolve symbolic links (2020-02-03)
+    FRANGI3_PY_FOLDER = r"G:\home\eric\Code\brick\def\frangi3\frangi_py"
+    assert ph_.isdir(FRANGI3_PY_FOLDER)
+else:
+    FRANGI3_PY_FOLDER = ph_.dirname(
+        ph_.realpath(ph_.join(BRICK_FOLDER_PATH, "processing", f"{FRANGI3_PREFIX}.py"))
+    )
+DATA_ELEMENTS = (
+    (BRICK_FOLDER_PATH, BRICK_FOLDER),
+    (PARAMETERS_PATH, "."),
+)
+BINARY_ELEMENTS = (
+    (f"{ph_.join(FRANGI3_PY_FOLDER, FRANGI3_PREFIX)}-{OS_NAME}.so", "."),
+)
+
+arguments = [
+    f"--distpath={PER_OS_DIST_FOLDER_PATH}",
+    f"--specpath={PER_OS_BUILD_FOLDER_PATH}",
+    f"--workpath={PER_OS_BUILD_FOLDER_PATH}",
+    "--noconfirm",
+    "--onedir",
+    PY_SCRIPT_PATH,
+]
+for elm_type, elm_list in zip(
+    ("--add-data", "--add-binary"), (DATA_ELEMENTS, BINARY_ELEMENTS)
+):
+    for element in elm_list:
+        arguments.insert(
+            arguments.__len__() - 1, f"{elm_type}={element[0]}{PATH_SEP}{element[1]}"
+        )
+
+for resource in gb_.glob(ph_.join(RES_FOLDER_PATH, f"{RES_PREFIX}*.tif")):
+    arguments.insert(
+        arguments.__len__() - 1, f"--add-data={resource}{PATH_SEP}{DST_RES_FOLDER}"
+    )
+
+dependencies = []
+with open(DEP_LIST_DOC) as doc_accessor:
+    for line in doc_accessor:
+        if (line.__len__() == 0) or line.isspace() or line.startswith("#"):
+            continue
+        module = line.split("=")[0].rstrip()
+        dependencies.append(module)
+        deps_info = sp_.check_output(
+            [sy_.executable, "-m", "pip", "show", module]
+        ).decode()
+        sub_deps = ()
+        for dep_info in deps_info.split("\n")[:-1]:
+            # [:-1]: Excludes the last, empty line
+            if dep_info.startswith(REQUIREMENTS_MARKER):
+                dep_info_wo_marker = dep_info[REQUIREMENTS_MARKER.__len__() :]
+                if "," in dep_info_wo_marker:
+                    sub_deps = dep_info_wo_marker.split(",")
+                elif not dep_info_wo_marker.isspace():
+                    sub_deps = [dep_info_wo_marker]
+                break
+        for sub_dep in sub_deps:
+            dependencies.append(sub_dep.strip())
+dependencies = sorted(set(dependencies))
+for dep in dependencies:
+    arguments.insert(arguments.__len__() - 1, f"--hidden-import={dep}")
+
+excluded_modules_w_version = sp_.check_output(
+    [sy_.executable, "-m", "pip", "freeze"]
+).decode()
+excluded_modules = []
+for module in excluded_modules_w_version.split("\n")[:-1]:
+    # [:-1]: Excludes the last, empty line
+    excluded_modules.append(module.split("=")[0])
+excluded_modules = set(excluded_modules) - set(dependencies)
+for module in excluded_modules:
+    arguments.insert(arguments.__len__() - 1, f"--exclude-module={module}")
+
+for readme in gb_.glob(InBaseFolder(f"{README_PREFIX}*")):
+    readme = ph_.realpath(readme)
+    arguments.insert(arguments.__len__() - 1, f"--add-data={readme}{PATH_SEP}.")
+
+if OS_NAME == "nt":
+    arguments.insert(arguments.__len__() - 1, "--console")
+
+print("--- Launching PyInstaller with arguments:")
+pp_.pprint(arguments)
+PyInstaller.__main__.run(arguments)
+
+print("--- Moving/copying elements into place")
+if OS_NAME == "nt":
+    sh_.copy(f"{SCRIPT_NAME}.bat", PER_OS_DIST_FOLDER_PATH)
+else:
+    print(f"    /!\\ TODO: MAKE a SHELL SCRIPT for {OS_NAME.upper()} and COPY IT")
+sh_.move(ph_.join(PER_OS_and_SCRIPT_DIST_PATH, PARAMETERS), PER_OS_DIST_FOLDER_PATH)
+sh_.move(ph_.join(PER_OS_and_SCRIPT_DIST_PATH, DST_RES_FOLDER), PER_OS_DIST_FOLDER_PATH)
+for readme in gb_.glob(ph_.join(PER_OS_and_SCRIPT_DIST_PATH, f"{README_PREFIX}*")):
+    sh_.move(readme, PER_OS_DIST_FOLDER_PATH)
+
+print("--- Creating ZIP archive")
+with zp_.ZipFile(
+    ph_.join(DIST_ROOT_FOLDER, f"{PER_OS_DIST_FOLDER}.zip"),
+    mode="w",
+    compression=zp_.ZIP_DEFLATED,
+    compresslevel=9,
+) as archive:
+    for folder, _, documents in os_.walk(PER_OS_DIST_FOLDER_PATH):
+        for document in documents:
+            doc_path = ph_.join(folder, document)
+            archive.write(
+                doc_path, arcname=ph_.relpath(doc_path, start=DIST_ROOT_FOLDER)
+            )
diff --git a/standalone/lin-to-win.txt b/standalone/lin-to-win.txt
deleted file mode 100644
index 9ab12e4e5f256a6294e5c2b56de4aa4b00188516..0000000000000000000000000000000000000000
--- a/standalone/lin-to-win.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-Remove all brick... hierarchy in imports
-Remove hierarchy in c-extension loading in frangi3.py
-Change name nutrimorph.py into main.py
-Change name parameters.py into main_prm.py
-In main.py (re-check necessity periodically as this should not be necessary):
-    > import tifffile
-    Then
-    < assert image.ndim == 3 # TODO: replace assertion with proper exception handling
-    ---
-    > if image.ndim == 4:
-    >     image = image[:,:,:,0]
-    > assert image.ndim == 3, f"Image dimension: {image.ndim}={image.shape}, expected 3"
-
---- Some random notes (should be obsolete)
-
-If tifffile is missing, then DIO_6H_6_1.70bis_2.2_3.tif, when read with skimage.imread, appears as a 4-D (last dim=color) image which only contains zeros in the first channel.
diff --git a/standalone/setup.py b/standalone/setup.py
deleted file mode 100644
index 93728a2f0680d4e21fdd3da6854fb221e990d728..0000000000000000000000000000000000000000
--- a/standalone/setup.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from distutils.core import setup
-
-import numpy as np_
-from Cython.Build import cythonize
-
-
-setup(
-    ext_modules=cythonize("frangi_3d.py"),
-    requires=["numpy", "scipy"],
-    include_dirs=[np_.get_include()],
-)