Browse Source

refactoring of the tkinter settings window

asobolev 4 years ago
parent
commit
32cdc14a27
3 changed files with 138 additions and 129 deletions
  1. 8 0
      .gitignore
  2. 113 129
      Jupyter Notebook - One Target Island - openCV 4-0-1.ipynb
  3. 17 0
      defaults.json

+ 8 - 0
.gitignore

@@ -0,0 +1,8 @@
+# user generated files
+*.png
+*parameters.txt
+*.xlsx
+*.avi
+
+# ipython temp files
+.ipynb_checkpoints

+ 113 - 129
Jupyter Notebook - One Target Island - openCV 4-0-1.ipynb

@@ -26,7 +26,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 1,
+   "execution_count": 55,
    "metadata": {},
    "outputs": [
     {
@@ -49,84 +49,62 @@
     "from scipy.io  import wavfile             # WAV-file import filter\n",
     "from pyfirmata import Arduino             # Arduino support\n",
     "from math      import e                   # Euler's number\n",
+    "from collections import OrderedDict\n",
     "\n",
     "import math                               # Import math module\n",
     "import time                               # Import time module for time measurements and pausing\n",
-    "import random                             # Import random module for random number generation\n"
+    "import random                             # Import random module for random number generation\n",
+    "import json\n",
+    "import datetime"
    ]
   },
   {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "## Define a custom function"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 2,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "# Function that defines global variables based on user inputs at a starting screen (below)\n",
-    "def show_entry_fields():\n",
-    "    \n",
-    "    print('Trials per Session: %s' % e1.get())\n",
-    "    print('Session Duration: %s' % e2.get())\n",
-    "    print('Trial Duration: %s' % e3.get())\n",
-    "    print('Radius of the Starting Platform: %s' % e4.get())\n",
-    "    print('X-Coordinate of the Starting Platform: %s' % e5.get())\n",
-    "    print('Y-Coordinate of the Starting Platform: %s' % e6.get())\n",
-    "    print('Radius of the target platform: %s' % e7.get())\n",
-    "    print('Target duration: %s' % e8.get())\n",
-    "    print('Subject and Date: %s' % e9.get())\n",
-    "    print('Subject is darker than background: %s' % e10.get())\n",
-    "    print('Initialization Duration: %s' % e11.get())\n",
-    "    \n",
-    "    global trialNumber \n",
-    "    trialNumber = int(e1.get())\n",
-    "    global sessionDuration \n",
-    "    sessionDuration = int(e2.get())\n",
-    "    global trialDuration \n",
-    "    trialDuration = int(e3.get())\n",
-    "    global startRadius\n",
-    "    startRadius = int(e4.get())\n",
-    "    global startX\n",
-    "    startX = int(e5.get())\n",
-    "    global startY\n",
-    "    startY = int(e6.get())\n",
-    "    global targetRadius\n",
-    "    targetRadius = int(e7.get())\n",
-    "    global targetDuration\n",
-    "    targetDuration = float(e8.get())\n",
-    "    global experimentID\n",
-    "    experimentID = e9.get()\n",
-    "    global backgroundColor\n",
-    "    backgroundColor = e10.get()\n",
-    "    global initDuration\n",
-    "    initDuration = float(e11.get())\n"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Set the arena dimensions\n",
+    "## Load default session settings\n",
     "\n",
-    "Here, the arena position and dimensions can be defined. In the example setup, a circular arena of 80 cm radius is filmed by a USB-webcam with a resolution of 800*600 px. In the cell below, the arena dimensions optimally use the resolution of the webcam in terms of spatial resolution of the later tracking. You may have to redefine the values in the next cell to fit your combination of camera resolution and arena dimensions."
+    "For every particular experimental cofiguration one can copy the 'defaults.json' file as a specific experimental preset and load it here instead of 'defaults.json'."
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 3,
-   "metadata": {},
-   "outputs": [],
+   "execution_count": 56,
+   "metadata": {
+    "scrolled": false
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "    \"trial_number\": 50,\n",
+      "    \"session_duration\": 3600,\n",
+      "    \"trial_duration\": 60,\n",
+      "    \"start_radius\": 67,\n",
+      "    \"start_x\": 195,\n",
+      "    \"start_y\": 195,\n",
+      "    \"target_radius\": 80,\n",
+      "    \"target_duration\": 5,\n",
+      "    \"subject\": \"003901\",\n",
+      "    \"experiment_type\": \"aSIT\",\n",
+      "    \"background_color\": \"T\",\n",
+      "    \"init_duration\": 0.2,\n",
+      "    \"arena_x\": 400,\n",
+      "    \"arena_y\": 300,\n",
+      "    \"arena_radius\": 300,\n",
+      "    \"experiment_date\": \"2020-06-07_18-02-04\"\n",
+      "}\n"
+     ]
+    }
+   ],
    "source": [
-    "# Arena coordinates and radius (best set to maximum spatial resolution at given image size)\n",
-    "# Here: Video resolution = 800*600\n",
-    "arenaX      = 400\n",
-    "arenaY      = 300\n",
-    "arenaRadius = 300"
+    "with open('defaults.json') as json_file:\n",
+    "    cfg = OrderedDict(json.load(json_file))\n",
+    "cfg['experiment_date'] = datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')\n",
+    "\n",
+    "print(json.dumps(cfg, indent=4))"
    ]
   },
   {
@@ -146,84 +124,90 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
-   "metadata": {},
+   "execution_count": 58,
+   "metadata": {
+    "scrolled": true
+   },
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "Trials per Session: 50\n",
-      "Session Duration: 3600\n",
-      "Trial Duration: 60\n",
-      "Radius of the Starting Platform: 67\n",
-      "X-Coordinate of the Starting Platform: 195\n",
-      "Y-Coordinate of the Starting Platform: 195\n",
-      "Radius of the target platform: 80\n",
-      "Target duration: 5\n",
-      "Subject and Date: SubjectID_ExpType_MM_DD_20YY\n",
-      "Subject is darker than background: T\n",
-      "Initialization Duration: 0.2\n"
+      "EXPERIMENT ID: 003901_aSIT_2020-06-07_18-02-04\n",
+      "Trials per session: 50\n",
+      "Session duration [s]: 3600\n",
+      "Trial duration [s]: 60\n",
+      "Radius of the starting platform [pixels]: 67\n",
+      "X-position of the starting platform [pixels]: 195\n",
+      "Y-position of the starting platform [pixels]: 195\n",
+      "Radius of the target platform [pixels]: 80\n",
+      "Target duration [s]: 5\n",
+      "Subject: 003901\n",
+      "Experiment type: aSIT\n",
+      "Subject is darker than background [T = True; F = False]: T\n",
+      "Initialisation Duration [s]: 0.2\n",
+      "Arena X coordinate [pixels]: 400\n",
+      "Arena Y coordinate [pixels]: 300\n",
+      "Arena radius [pixels]: 300\n",
+      "Experiment date: 2020-06-07_18-02-04\n"
      ]
     }
    ],
    "source": [
+    "def show_entry_fields():\n",
+    "    print(\"EXPERIMENT ID: %s\" % experiment_id)\n",
+    "    for key, field in entry_fields.items():\n",
+    "        print(\"%s: %s\" % (labels[key].cget('text'), entry_fields[key].get()))\n",
+    "        \n",
+    "def update_config():\n",
+    "    for key, entry_field in entry_fields.items():\n",
+    "        cfg[key] = entry_field.get()\n",
+    "    experiment_id = \"%s_%s_%s\" % (cfg['subject'], cfg['experiment_type'], cfg['experiment_date'])\n",
+    "        \n",
+    "def show_and_update_config():\n",
+    "    update_config()\n",
+    "    show_entry_fields()\n",
+    "    \n",
     "# Starting screen\n",
     "master = tk.Tk()\n",
     "master.title('Experimental parameters')\n",
+    "\n",
+    "# Labels\n",
     "tk.Label(master, text=\"Instructions: \\n 1. Enter parameters (only integers are allowed as numbers) \\n 2. Press 'Apply' \\n 3. Press 'Continue'\").grid(row=0, padx=10, pady=10)\n",
-    "tk.Label(master, text=\"Trials per session\").grid(row=4, padx=5, pady=5)\n",
-    "tk.Label(master, text=\"Session duration [s]\").grid(row=5, padx=5, pady=5)\n",
-    "tk.Label(master, text=\"Trial duration [s]\").grid(row=6, padx=5, pady=5)\n",
-    "tk.Label(master, text=\"Radius of the starting platform [pixels]\").grid(row=7, padx=5, pady=5)\n",
-    "tk.Label(master, text=\"X-position of the starting platform [pixels]\").grid(row=8, padx=5, pady=5)\n",
-    "tk.Label(master, text=\"Y-position of the starting platform [pixels]\").grid(row=9, padx=5, pady=5)\n",
-    "tk.Label(master, text=\"Radius of the target platform [pixels]\").grid(row=10, padx=5, pady=5)\n",
-    "tk.Label(master, text=\"Target duration [s]\").grid(row=11, padx=5, pady=5)\n",
-    "tk.Label(master, text=\"Experiment ID [subject_date]\").grid(row=12, padx=5, pady=5)\n",
-    "tk.Label(master, text=\"Subject is darker than background [T = True; F = False]\").grid(row=13, padx=5, pady=5)\n",
-    "tk.Label(master, text=\"Initialisation Duration [s]\").grid(row=14, padx=5, pady=5)\n",
-    "\n",
-    "e1 = tk.Entry(master)\n",
-    "e1.insert('end', '50')\n",
-    "e2 = tk.Entry(master)\n",
-    "e2.insert('end', '3600')\n",
-    "e3 = tk.Entry(master)\n",
-    "e3.insert('end', '60')\n",
-    "e4 = tk.Entry(master)\n",
-    "e4.insert('end', '67')\n",
-    "e5 = tk.Entry(master)\n",
-    "e5.insert('end', '195')\n",
-    "e6 = tk.Entry(master)\n",
-    "e6.insert('end', '195')\n",
-    "e7 = tk.Entry(master)\n",
-    "e7.insert('end', '80')\n",
-    "e8 = tk.Entry(master)\n",
-    "e8.insert('end', '5')\n",
-    "e9 = tk.Entry(master)\n",
-    "e9.insert('end', 'SubjectID_ExpType_MM_DD_20YY')\n",
-    "e10 = tk.Entry(master)\n",
-    "e10.insert('end', 'T')\n",
-    "e11 = tk.Entry(master)\n",
-    "e11.insert('end', '0.2')\n",
-    "\n",
-    "e1.grid(row=4, column=1)\n",
-    "e2.grid(row=5, column=1)\n",
-    "e3.grid(row=6, column=1)\n",
-    "e4.grid(row=7, column=1)\n",
-    "e5.grid(row=8, column=1)\n",
-    "e6.grid(row=9, column=1)\n",
-    "e7.grid(row=10, column=1)\n",
-    "e8.grid(row=11, column=1)\n",
-    "e9.grid(row=12, column=1)\n",
-    "e10.grid(row=13, column=1)\n",
-    "e11.grid(row=14, column=1)\n",
-    "\n",
-    "tk.Button(master, text='Apply', command=show_entry_fields).grid(row=15, column=0, sticky='s', pady=4)\n",
-    "tk.Button(master, text='Continue', command=master.destroy).grid(row=15, column=1, sticky='w', pady=4)\n",
-    "\n",
-    "tk.mainloop()\n",
-    "\n"
+    "labels = OrderedDict()\n",
+    "labels['trial_number'] = tk.Label(master, text=\"Trials per session\")\n",
+    "labels['session_duration'] = tk.Label(master, text=\"Session duration [s]\")\n",
+    "labels['trial_duration'] = tk.Label(master, text=\"Trial duration [s]\")\n",
+    "labels['start_radius'] = tk.Label(master, text=\"Radius of the starting platform [pixels]\")\n",
+    "labels['start_x'] = tk.Label(master, text=\"X-position of the starting platform [pixels]\")\n",
+    "labels['start_y'] = tk.Label(master, text=\"Y-position of the starting platform [pixels]\")\n",
+    "labels['target_radius'] = tk.Label(master, text=\"Radius of the target platform [pixels]\")\n",
+    "labels['target_duration'] = tk.Label(master, text=\"Target duration [s]\")\n",
+    "labels['subject'] = tk.Label(master, text=\"Subject\")\n",
+    "labels['experiment_type'] = tk.Label(master, text=\"Experiment type\")\n",
+    "labels['background_color'] = tk.Label(master, text=\"Subject is darker than background [T = True; F = False]\")\n",
+    "labels['init_duration'] = tk.Label(master, text=\"Initialisation Duration [s]\")\n",
+    "labels['arena_x'] = tk.Label(master, text=\"Arena X coordinate [pixels]\")\n",
+    "labels['arena_y'] = tk.Label(master, text=\"Arena Y coordinate [pixels]\")\n",
+    "labels['arena_radius'] = tk.Label(master, text=\"Arena radius [pixels]\")\n",
+    "labels['experiment_date'] = tk.Label(master, text=\"Experiment date\")\n",
+    "\n",
+    "for i, (key, label) in enumerate(labels.items()):\n",
+    "    label.grid(row=i + 4, padx=5, pady=5)\n",
+    "\n",
+    "# Entry fields\n",
+    "entry_fields = OrderedDict()\n",
+    "for i, (key, value) in enumerate(cfg.items()):\n",
+    "    entry_fields[key] = tk.Entry(master)\n",
+    "    entry_fields[key].insert('end', value)\n",
+    "    entry_fields[key].grid(row=i + 4, column=1)\n",
+    "\n",
+    "experiment_id = \"%s_%s_%s\" % (cfg['subject'], cfg['experiment_type'], cfg['experiment_date'])\n",
+    "\n",
+    "tk.Button(master, text='Apply', command=show_and_update_config).grid(row=len(entry_fields) + 4, column=0, sticky='s', pady=4)\n",
+    "tk.Button(master, text='Continue', command=master.destroy).grid(row=len(entry_fields) + 4, column=1, sticky='w', pady=4)\n",
+    "\n",
+    "tk.mainloop()"
    ]
   },
   {

+ 17 - 0
defaults.json

@@ -0,0 +1,17 @@
+{
+    "trial_number": 50,
+    "session_duration": 3600,
+    "trial_duration": 60,
+    "start_radius": 67,
+    "start_x": 195,
+    "start_y": 195,
+    "target_radius": 80,
+    "target_duration": 5,
+    "subject": "003901",
+    "experiment_type": "aSIT",
+    "background_color": "T",
+    "init_duration": 0.2,
+    "arena_x": 400,
+    "arena_y": 300,
+    "arena_radius": 300
+}