diff --git a/analysis.ipynb b/analysis.ipynb
index 6ef876e5ad0b19af4b38e40b8bc76cc7f61672fb..586a14ddc60189a8868ca5aecb9903014205c025 100644
--- a/analysis.ipynb
+++ b/analysis.ipynb
@@ -2,20 +2,27 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": 1,
+   "execution_count": 20,
    "metadata": {},
    "outputs": [],
    "source": [
-    "%run \"functions.py\"\n",
     "%matplotlib inline\n",
     "\n",
+    "import os\n",
+    "\n",
     "import ipywidgets as widgets\n",
     "from ipywidgets import interactive, fixed, HBox, VBox\n",
     "from ipyfilechooser import FileChooser\n",
     "from IPython.display import HTML, Markdown, display, clear_output\n",
     "\n",
-    "def printmd(string):\n",
-    "    display(Markdown(string))"
+    "import manipylator\n",
+    "import manipylator.utils as utils \n",
+    "import manipylator.gui as gui\n",
+    "from manipylator.utils import printmd \n",
+    "from manipylator.analysis import tune_detect_bead\n",
+    "from manipylator.controller import Controller, get_stage_prop\n",
+    "\n",
+    "cwd = os.getcwd()"
    ]
   },
   {
@@ -27,7 +34,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 2,
+   "execution_count": 21,
    "metadata": {},
    "outputs": [
     {
@@ -57,7 +64,7 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "68f8d68620004dfd8378451cd71b4f65",
+       "model_id": "a24127a5a5b445ffb61b45cf20a874fe",
        "version_major": 2,
        "version_minor": 0
       },
@@ -79,7 +86,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 138,
+   "execution_count": 23,
    "metadata": {},
    "outputs": [
     {
@@ -97,12 +104,12 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "3a64141e9ab549a4bd448b2cb9d4ac18",
+       "model_id": "0bf65887ccf144a9a7d9e31c5a968559",
        "version_major": 2,
        "version_minor": 0
       },
       "text/plain": [
-       "FileChooser(path='/Users/amichaut/Desktop/selected_spheroids', filename='', title='HTML(value='', layout=Layou…"
+       "FileChooser(path='/Users/amichaut/Desktop', filename='', title='HTML(value='', layout=Layout(display='none'))'…"
       ]
      },
      "metadata": {},
@@ -219,7 +226,7 @@
     "chirp_wid = widgets.Button(value=True, description=description)\n",
     "\n",
     "def make_chirp_info(obj):\n",
-    "    write_dict(exp_chirp,info_fn)\n",
+    "    utils.write_dict(exp_chirp,info_fn)\n",
     "    \n",
     "chirp_wid.on_click(make_chirp_info)\n",
     "\n",
@@ -228,7 +235,7 @@
     "PID_wid = widgets.Button(value=True, description=description)\n",
     "\n",
     "def make_PID_info(obj):\n",
-    "    write_dict(exp_PID,info_fn)\n",
+    "    utils.write_dict(exp_PID,info_fn)\n",
     "    \n",
     "PID_wid.on_click(make_PID_info)\n",
     "\n",
@@ -237,7 +244,7 @@
     "sweep_wid = widgets.Button(value=True, description=description)\n",
     "\n",
     "def make_sweep_info(obj):\n",
-    "    write_dict(exp_sweep,info_fn)\n",
+    "    utils.write_dict(exp_sweep,info_fn)\n",
     "    \n",
     "sweep_wid.on_click(make_sweep_info)\n",
     "\n",
@@ -317,7 +324,7 @@
     "image = stack[0]\n",
     "h,w = image.shape\n",
     "\n",
-    "interactive_plot_param = interactive(select_ROI,\n",
+    "interactive_plot_param = interactive(utils.select_ROI,\n",
     "                                     x_range=widgets.IntRangeSlider(min=0,max=w,value=[0,w],continuous_update=False),\n",
     "                                     y_range=widgets.IntRangeSlider(min=0,max=h,value=[0,h],continuous_update=False),\n",
     "                                     intensity_range=widgets.IntRangeSlider(min=0,max=255,value=[0,255],continuous_update=False),\n",
@@ -1125,7 +1132,7 @@
     "\n",
     "# def make_flow_info(obj):\n",
     "#     exp_flow['tip_radius'] = np.sqrt(exp_flow['contact_area']/np.pi)/lengthscale\n",
-    "#     write_dict(exp_flow,osp.join(exp_flow['exp_dir'],'info.csv'))\n",
+    "#     utils.write_dict(exp_flow,osp.join(exp_flow['exp_dir'],'info.csv'))\n",
     "    \n",
     "# flow_wid.on_click(make_flow_info)"
    ]
diff --git a/manipylator/gui.py b/manipylator/gui.py
index 0ba3b00e8a554a6476952063f34dab391df802b9..c7853c19df6e3f542893d7cc317115166c5ce357 100644
--- a/manipylator/gui.py
+++ b/manipylator/gui.py
@@ -53,10 +53,31 @@ def printmd(string):
     display(Markdown(string))
 
 
+def generate_show_pos(controller,output):
+    """
+    A function wrapper that generates a function to be passed to Widget on_click method
+    controller: controller.Controller object 
+    output: ipywidgets.Output object
+    """
+
+    def show_pos(obj):
+        """
+        a function used to show the stage position when button clicked
+        """
+        output.clear_output()
+        pos = controller.get_pos(print_pos=False)
+        with output:
+            print('raw position = {} um\n'.format(pos))
+            print('transformed position = {} um\n'.format(controller.stage_pos))
+
+    return show_pos
+
+
+
 def make_basic_dashboard(controller_dict, virtual):
     """
     Make a dashboard to control the position and the servo of the connected controllers
-    controller_dict: dict of Controller object 
+    controller_dict: dict of controller.Controller object 
     virtual: bool if True controller are virtual
     """
 
@@ -98,41 +119,9 @@ def make_basic_dashboard(controller_dict, virtual):
         
         # show position button
         out = widgets.Output()  # output to display position
-
-        ### !!! quick and dirty solution that needs to be better addressed !!!
-        ### prevent show_pos to be updated by the loop by giving it another name
-        ### works only for 2 controllers
-        if i == 0:
-            def show_pos_0(obj):
-                """
-                a function used to show the stage position when button clicked
-                """
-                out = out_list[0]
-                controller = controller_list[0]
-                out.clear_output()
-                pos = controller.get_pos(print_pos=False)
-                with out:
-                    print('raw position = {} um\n'.format(pos))
-                    print('transformed position = {} um\n'.format(controller.stage_pos))
-        elif i == 1:
-            def show_pos_1(obj):
-                """
-                a function used to show the stage position when button clicked
-                """
-                out = out_list[1]
-                controller = controller_list[1]
-                out.clear_output()
-                pos = controller.get_pos(print_pos=False)
-                with out:
-                    print('raw position = {} um\n'.format(pos))
-                    print('transformed position = {} um\n'.format(controller.stage_pos))
-
-        pos_wid = widgets.Button(value=True, description='Show position')
-
-        if i == 0:
-            pos_wid.on_click(show_pos_0)
-        elif i == 1:
-            pos_wid.on_click(show_pos_1)
+        pos_wid = widgets.Button(value=True, description='Show position')  # button widget
+        show_pos = generate_show_pos(controller,out)  # function to show position when button click
+        pos_wid.on_click(show_pos)
 
 
         # store widgets, outputs and labels
diff --git a/stage_controler.ipynb b/stage_controler.ipynb
index bcf36eade706509e8d8fe09c6b6d12cc1fa5f011..d40e0f53867b057531b7a9421ee18a7d01e471e8 100755
--- a/stage_controler.ipynb
+++ b/stage_controler.ipynb
@@ -74,7 +74,7 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "ac1bf6070c7f422db84ba9dd637998e5",
+       "model_id": "37fa5a36f5b048a9b323f4e9216895f5",
        "version_major": 2,
        "version_minor": 0
       },
@@ -100,7 +100,7 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "2216025f69ba44daa1d01f96a907fff0",
+       "model_id": "cd1e6b69d8c64b27b54e8623f4d08b70",
        "version_major": 2,
        "version_minor": 0
       },
@@ -126,12 +126,12 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "9064d96ce5344a8793140b64d91e1312",
+       "model_id": "3a116fcf137a4c8fb667bbfe83db4ffe",
        "version_major": 2,
        "version_minor": 0
       },
       "text/plain": [
-       "ToggleButton(value=True, description='Virtual stage')"
+       "ToggleButton(value=False, description='Virtual stage')"
       ]
      },
      "metadata": {},
@@ -218,7 +218,7 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "32759c64f20f4d469d57b12a17d4a3cf",
+       "model_id": "f3556e2d23ce4f0aa7d7ab4c44494144",
        "version_major": 2,
        "version_minor": 0
       },
@@ -232,7 +232,7 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "d60017a2c2a34b7cac0ad1322768790b",
+       "model_id": "b6214ad935aa47f79aba7d57995b65be",
        "version_major": 2,
        "version_minor": 0
       },