diff --git a/README.md b/README.md
index 70ab553..c01f1ff 100755
--- a/README.md
+++ b/README.md
@@ -1,2 +1,25 @@
# RPi4_behavior_boxes
BehavBox is a system with Raspberry Pi computers that is sufficient to provide a foundation of constructing animal behavior training and experiment.
+
+# Quick Start
+in task_protocol, you could find all the task examples. Each task has its run file, task file, task information file and an example of session_information file.
+
+To start running a task file, you need to first create a session_information pathway and session_information file in a path (suggested) in the home directory and outside of the git repo since you would have to configure and changes the file everyday for training purposes.
+
+After configure the session_information path and input the appropriate path leading to the exact session_information of the date, you could do python3 run_x_task.py to start running the task.
+
+# Example
+To start running the task `headfixed_task.py`
+1. Setup and configure the 'session_information_year-month-date.py' file:
+first, create the experimental_data directory in the home directory path:
+`$ mkdir ~/experimental_data`
+second, create all the necessary subdirectories for the specific task:
+`$ mkdir ~/experimental_data/headfixed_task`
+`$ mkdir ~/experimental_data/headfixed_task/session_info`
+then, copy the session_information example file corresponding to the specific task:
+`$ cp ~/RPi4_behavbior_boxes/task_protocol/headfixed_task/session_info_headfixed_independent_reward.py ~/experimental_data/headfixed_task/session_info`
+2. Modify the newly created session_info file:
+`$ sudo nano ~/experimental_data/headfixed_task/session_info_headfixed_independent_reward.py`
+**KEEP IN MIND** after configuring the session_information to manually change the field manual date to the day of the experiment session (the day of the experiment), and the name of the session_info file from `session_info_headfixed_independent_reward.py` to `session_info_year-month-date.py`. Otherwise, an error would occur when running the task file.
+3. After setting up the session_info file, run the task:
+`$ python3 ~/RPi4_behavior_boxes/task_protocol/headfixed_task/run_headfixed_task.py`
\ No newline at end of file
diff --git a/picamera_library_modified/picamera.egg-info/dependency_links.txt b/debug/__init__.py
old mode 100755
new mode 100644
similarity index 100%
rename from picamera_library_modified/picamera.egg-info/dependency_links.txt
rename to debug/__init__.py
diff --git a/calibrate.py b/debug/calibrate.py
similarity index 100%
rename from calibrate.py
rename to debug/calibrate.py
diff --git a/camera_test.py b/debug/camera_test.py
similarity index 100%
rename from camera_test.py
rename to debug/camera_test.py
diff --git a/control_preview.py b/debug/control_preview.py
similarity index 100%
rename from control_preview.py
rename to debug/control_preview.py
diff --git a/debug/generate_reward_trajectory.py b/debug/generate_reward_trajectory.py
new file mode 100644
index 0000000..4d2cbed
--- /dev/null
+++ b/debug/generate_reward_trajectory.py
@@ -0,0 +1,45 @@
+def cumsum_positive(input_list):
+ for index in range(len(input_list)):
+ if index == 0 and input_list[index]<0:
+ input_list[index] = -input_list[index]
+ elif input_list[index]+input_list[index-1]<0:
+ input_list[index] = input_list[index] - input_list[index-1]
+ else:
+ input_list[index] = input_list[index] + input_list[index-1]
+ return input_list
+
+def generate_reward_trajectory(scale=0.5, offset=3.0, change_point=20, ntrials=200):
+ # initial reward (need to be random)
+ rewards_L = [1]
+ rewards_R = [1]
+ for a in np.arange(np.round(ntrials / change_point)):
+ temp = np.random.randn(change_point) * scale
+ # temp = np.random.uniform(low=0.0, high=10, size=(change_point,))
+
+ # print("ay o" + str(temp))
+ # while temp < 0:
+ # temp = np.random.randn(change_point) * scale
+ rewards_L.append(cumsum_positive(temp) + offset)
+ temp = np.random.randn(change_point) * scale
+ # temp = np.random.uniform(low=0.0, high=10, size=(change_point,))
+ # while temp < 0:
+ # temp = np.random.randn(change_point) * scale
+ rewards_R.append(cumsum_positive(temp) + offset)
+ rewards_L = np.hstack(rewards_L)
+ rewards_R = np.hstack(rewards_R)
+ # plt.plot(rewards_L,'b');plt.plot(rewards_R,'r--')
+ reward_LR = [rewards_L, rewards_R]
+ reward_LR = np.transpose(np.array(reward_LR))
+ reward_LR = reward_LR[0:ntrials, :]
+ # print(reward_LR)
+ return reward_LR
+
+# from reward_distribution import generate_reward_trajectory
+scale = 0.5
+offset = 3.0
+change_point = 20
+ntrials = 100
+
+reward_distribution_list = generate_reward_trajectory(scale, offset, change_point, ntrials)
+
+print(reward_distribution_list)
\ No newline at end of file
diff --git a/mounting_hard_drive.txt b/debug/mounting_hard_drive.txt
similarity index 100%
rename from mounting_hard_drive.txt
rename to debug/mounting_hard_drive.txt
diff --git a/press_button.py b/debug/press_button.py
similarity index 100%
rename from press_button.py
rename to debug/press_button.py
diff --git a/pump_debug.py b/debug/pump_debug.py
similarity index 70%
rename from pump_debug.py
rename to debug/pump_debug.py
index 946f369..dc0beda 100755
--- a/pump_debug.py
+++ b/debug/pump_debug.py
@@ -1,6 +1,9 @@
# pump_debug.py: it's for testing the pump class and the pump itself
import sys
import time
+# updated with reorganization (on 7/11/2023)
+import sys
+sys.path.insert(0,'/home/pi/RPi4_behavior_boxes/essential')
from behavbox import Pump
# from fake_session_info import fake_session_info
side = str(sys.argv[1])
diff --git a/pygame_debug.py b/debug/pygame_debug.py
similarity index 100%
rename from pygame_debug.py
rename to debug/pygame_debug.py
diff --git a/record_treadmill.py b/debug/record_treadmill.py
similarity index 100%
rename from record_treadmill.py
rename to debug/record_treadmill.py
diff --git a/record_video.py b/debug/record_video.py
similarity index 100%
rename from record_video.py
rename to debug/record_video.py
diff --git a/debug/reward_distribution.py b/debug/reward_distribution.py
new file mode 100644
index 0000000..8a066b2
--- /dev/null
+++ b/debug/reward_distribution.py
@@ -0,0 +1,24 @@
+import numpy as np
+
+def generate_reward_trajectory(scale=0.5, offset=3.0, change_point=20, ntrials=200):
+ # initial reward (need to be random)
+ rewards_L = [1]
+ rewards_R = [1]
+ for a in np.arange(np.round(ntrials/change_point)):
+ temp = np.random.randn(change_point)*scale
+ rewards_L.append(np.cumsum(temp, axis=-1) + offset)
+ temp = np.random.randn(change_point)*scale
+ rewards_R.append(np.cumsum(temp, axis=-1) + offset)
+ rewards_L=np.hstack(rewards_L)
+ rewards_R=np.hstack(rewards_R)
+ #plt.plot(rewards_L,'b');plt.plot(rewards_R,'r--')
+ reward_LR = [rewards_L, rewards_R]
+ reward_LR = np.transpose(np.array(reward_LR))
+ reward_LR = reward_LR[0:ntrials,:]
+ print(reward_LR)
+ return reward_LR
+# generate_reward_trajectory()
+# session_information['reward']['scale']
+# session_information['reward']['offset']
+# session_information['reward']['change_point']
+# session_information['reward']['ntrials']
\ No newline at end of file
diff --git a/debug/syringe_pump_pygame_debug.py b/debug/syringe_pump_pygame_debug.py
new file mode 100644
index 0000000..14cfaed
--- /dev/null
+++ b/debug/syringe_pump_pygame_debug.py
@@ -0,0 +1,93 @@
+import pygame
+# updated with reorganization (on 7/11/2023)
+import sys
+sys.path.insert(0,'/home/pi/RPi4_behavior_boxes/essential')
+from behavbox import Pump
+import numpy as np
+
+class Pump(object):
+ def __init__(self, session_info):
+ self.pump1 = LED(19)
+ self.pump2 = LED(20)
+ self.pump3 = LED(21)
+ self.pump4 = LED(7)
+ self.pump_air = LED(8)
+ self.pump_vacuum = LED(25)
+ self.reward_list = [] # a list of tuple (pump_x, reward_amount) with information of reward history for data
+ # visualization
+
+ def reward(self, which_pump, reward_size):
+ # import coefficient from the session_information
+ coefficient_p1 = [0.13, 0]
+ coefficient_p2 = [0.13, 0]
+ coefficient_p3 = [0.13, 0]
+ coefficient_p4 = [0.13, 0]
+ duration_air = 1
+ duration_vac = 1
+
+ if which_pump == "1":
+ duration = round((coefficient_p1[0] * (reward_size / 1000) + coefficient_p1[1]), 5) # linear function
+ self.pump1.blink(duration, 0.1, 1)
+ self.reward_list.append(("pump1_reward", reward_size))
+ logging.info(";" + str(time.time()) + ";[reward];pump1_reward(reward_coeff: " + str(coefficient_p1) +
+ ", reward_amount: " + str(reward_size) + "duration: " + str(duration) + ")")
+ elif which_pump == "2":
+ duration = round((coefficient_p2[0] * (reward_size / 1000) + coefficient_p2[1]), 5) # linear function
+ self.pump2.blink(duration, 0.1, 1)
+ self.reward_list.append(("pump2_reward", reward_size))
+ logging.info(";" + str(time.time()) + ";[reward];pump2_reward(reward_coeff: " + str(coefficient_p2) +
+ ", reward_amount: " + str(reward_size) + "duration: " + str(duration) + ")")
+ elif which_pump == "3":
+ duration = round((coefficient_p3[0] * (reward_size / 1000) + coefficient_p3[1]), 5) # linear function
+ self.pump3.blink(duration, 0.1, 1)
+ self.reward_list.append(("pump3_reward", reward_size))
+ logging.info(";" + str(time.time()) + ";[reward];pump3_reward(reward_coeff: " + str(coefficient_p3) +
+ ", reward_amount: " + str(reward_size) + "duration: " + str(duration) + ")")
+ elif which_pump == "4":
+ duration = round((coefficient_p4[0] * (reward_size / 1000) + coefficient_p4[1]), 5) # linear function
+ self.pump4.blink(duration, 0.1, 1)
+ self.reward_list.append(("pump4_reward", reward_size))
+ logging.info(";" + str(time.time()) + ";[reward];pump4_reward(reward_coeff: " + str(coefficient_p4) +
+ ", reward_amount: " + str(reward_size) + "duration: " + str(duration) + ")")
+ elif which_pump == "air_puff":
+ self.pump_air.blink(duration_air, 0.1, 1)
+ self.reward_list.append(("air_puff", reward_size))
+ logging.info(";" + str(time.time()) + ";[reward];pump4_reward_" + str(reward_size))
+ elif which_pump == "vacuum":
+ self.pump_vacuum.blink(duration_vac, 0.1, 1)
+ logging.info(";" + str(time.time()) + ";[reward];pump_vacuum" + str(duration_vac))
+try:
+ pump = Pump()
+ pygame.init()
+ DISPLAYSURF = pygame.display.set_mode((200, 200))
+ pygame.display.set_caption("pygame debugging")
+except Exception as error_message:
+ print(str(error_message))
+
+run = True
+reward_size = float(input("Input reward_size: "))
+
+while run:
+ for event in pygame.event.get():
+ if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
+ run = False
+ if event.type == pygame.KEYDOWN:
+ # print("KeyDown: " + str(event.type) + "\n")
+ if event.key == pygame.K_q:
+ print("Q down: syringe pump 1")
+ pump.reward("1", reward_size)
+ if event.key == pygame.K_w:
+ print("W down: syringe pump 2")
+ pump.reward("2", reward_size)
+ if event.key == pygame.K_e:
+ print("E down: syringe pump 3")
+ pump.reward("3", reward_size)
+ if event.key == pygame.K_r:
+ print("R down: syringe pump 4")
+ pump.reward("4", reward_size)
+ if event.key == pygame.K_a:
+ print("A down: air puff on")
+ pump.reward("air_puff", reward_size)
+ if event.key == pygame.K_s:
+ print("S down: vacuum on")
+ pump.reward("vacuum", 1)
\ No newline at end of file
diff --git a/treadmill_debug.py b/debug/treadmill_debug.py
similarity index 100%
rename from treadmill_debug.py
rename to debug/treadmill_debug.py
diff --git a/environment/__init__.py b/environment/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/environment/__init__.py
@@ -0,0 +1 @@
+
diff --git a/essential/ADC/__init__.py b/essential/ADC/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/essential/ADC/__init__.py
@@ -0,0 +1 @@
+
diff --git a/ADC/readme.md b/essential/ADC/readme.md
similarity index 100%
rename from ADC/readme.md
rename to essential/ADC/readme.md
diff --git a/ADS1x15.py b/essential/ADS1x15.py
similarity index 100%
rename from ADS1x15.py
rename to essential/ADS1x15.py
diff --git a/FlipperOutput.py b/essential/FlipperOutput.py
similarity index 100%
rename from FlipperOutput.py
rename to essential/FlipperOutput.py
diff --git a/essential/RTC/__init__.py b/essential/RTC/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/essential/RTC/__init__.py
@@ -0,0 +1 @@
+
diff --git a/RTC/readme.md b/essential/RTC/readme.md
similarity index 100%
rename from RTC/readme.md
rename to essential/RTC/readme.md
diff --git a/Treadmill.py b/essential/Treadmill.py
similarity index 100%
rename from Treadmill.py
rename to essential/Treadmill.py
diff --git a/essential/__init__.py b/essential/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/essential/__init__.py
@@ -0,0 +1 @@
+
diff --git a/behavbox.py b/essential/behavbox.py
similarity index 69%
rename from behavbox.py
rename to essential/behavbox.py
index caeb719..d8aebf2 100755
--- a/behavbox.py
+++ b/essential/behavbox.py
@@ -104,13 +104,33 @@ def __init__(self, session_info):
# there is a DIO6, but that is the same pin as the camera strobe
###############################################################################################
- # IR detection - for nosepoke detection
+ # IR detection - for nosepoke
+ ###############################################################################################
+ self.IR_rx1 = Button(5, None, True) # None, True inverts the signal so poke=True, no-poke=False
+ self.IR_rx2 = Button(6, None, True)
+ self.IR_rx3 = Button(12, None, True)
+ self.IR_rx4 = Button(13, None, True) # (optional, reserved for future use
+ self.IR_rx5 = Button(16, None, True) # (optional, reserved for future use
+
+ # link nosepoke event detections to callbacks
+ self.IR_rx1.when_pressed = self.IR_1_entry
+ self.IR_rx2.when_pressed = self.IR_2_entry
+ self.IR_rx3.when_pressed = self.IR_3_entry
+ self.IR_rx4.when_pressed = self.IR_4_entry
+ self.IR_rx5.when_pressed = self.IR_5_entry
+ self.IR_rx1.when_released = self.IR_1_exit
+ self.IR_rx2.when_released = self.IR_2_exit
+ self.IR_rx3.when_released = self.IR_3_exit
+ self.IR_rx4.when_released = self.IR_4_exit
+ self.IR_rx5.when_released = self.IR_5_exit
+ ###############################################################################################
+ # close circuit detection - for ground pin circuit lick detection
###############################################################################################
self.lick1 = Button(26, None, True)
self.lick2 = Button(27, None, True)
self.lick3 = Button(15, None, True)
- self.reserved_rx1 = Button(13, None, True) # for mitch
- self.reserved_rx2 = Button(16, None, True) # for mitch
+ #self.reserved_rx1 = Button(13, None, True) # for mitch
+ #self.reserved_rx2 = Button(16, None, True) # for mitch
#
# # link nosepoke event detections to callbacks
self.lick1.when_pressed = self.left_exit
@@ -121,10 +141,10 @@ def __init__(self, session_info):
self.lick2.when_released = self.right_entry
self.lick3.when_released = self.center_entry
- self.reserved_rx1.when_pressed = self.reserved_rx1_pressed
- self.reserved_rx2.when_pressed = self.reserved_rx2_pressed
- self.reserved_rx1.when_released = self.reserved_rx1_released
- self.reserved_rx2.when_released = self.reserved_rx2_released
+ # self.reserved_rx1.when_pressed = self.reserved_rx1_pressed
+ # self.reserved_rx2.when_pressed = self.reserved_rx2_pressed
+ # self.reserved_rx1.when_released = self.reserved_rx1_released
+ # self.reserved_rx2.when_released = self.reserved_rx2_released
###############################################################################################
# sound: audio board DIO - pins sending TTL to the Tsunami soundboard via SMA connectors
@@ -142,7 +162,7 @@ def __init__(self, session_info):
###############################################################################################
# pump: trigger signal output to a driver board induce the solenoid valve to deliver reward
###############################################################################################
- self.pump = Pump()
+ self.pump = Pump(self.session_info)
###############################################################################################
# flipper strobe signal (previously called camera strobe signal)
@@ -260,39 +280,42 @@ def check_keybd(self):
self.keyboard_active = False
elif event.key == pygame.K_1:
self.left_entry()
+ self.left_IR_entry()
logging.info(";" + str(time.time()) + ";[action];key_pressed_left_entry()")
elif event.key == pygame.K_2:
self.center_entry()
+ self.center_IR_entry()
logging.info(";" + str(time.time()) + ";[action];key_pressed_center_entry()")
elif event.key == pygame.K_3:
self.right_entry()
+ self.right_IR_entry()
logging.info(";" + str(time.time()) + ";[action];key_pressed_right_entry()")
- elif event.key == pygame.K_4:
- self.reserved_rx1_pressed()
- logging.info(";" + str(time.time()) + ";[action];key_pressed_reserved_rx1_pressed()")
- elif event.key == pygame.K_5:
- self.reserved_rx2_pressed()
- logging.info(";" + str(time.time()) + ";[action];key_pressed_reserved_rx2_pressed()")
+ # elif event.key == pygame.K_4:
+ # self.reserved_rx1_pressed()
+ # logging.info(";" + str(time.time()) + ";[action];key_pressed_reserved_rx1_pressed()")
+ # elif event.key == pygame.K_5:
+ # self.reserved_rx2_pressed()
+ # logging.info(";" + str(time.time()) + ";[action];key_pressed_reserved_rx2_pressed()")
elif event.key == pygame.K_q:
# print("Q down: syringe pump 1 moves")
- logging.info(";" + str(time.time()) + ";[reward];key_pressed_pump1")
- self.pump.reward("1", 5)
+ # logging.info(";" + str(time.time()) + ";[reward];key_pressed_pump1")
+ self.pump.reward("key_1", self.session_info["key_reward_amount"])
elif event.key == pygame.K_w:
# print("W down: syringe pump 2 moves")
- logging.info(";" + str(time.time()) + ";[reward];key_pressed_pump2")
- self.pump.reward("2", 5)
+ # logging.info(";" + str(time.time()) + ";[reward];key_pressed_pump2")
+ self.pump.reward("key_2", self.session_info["key_reward_amount"])
elif event.key == pygame.K_e:
# print("E down: syringe pump 3 moves")
- logging.info(";" + str(time.time()) + ";[reward];key_pressed_pump3")
- self.pump.reward("3", 5)
+ # logging.info(";" + str(time.time()) + ";[reward];key_pressed_pump3")
+ self.pump.reward("key_3", self.session_info["key_reward_amount"])
elif event.key == pygame.K_r:
# print("R down: syringe pump 4 moves")
- logging.info(";" + str(time.time()) + ";[reward];key_pressed_pump4")
- self.pump.reward("4", 5)
+ # logging.info(";" + str(time.time()) + ";[reward];key_pressed_pump4")
+ self.pump.reward("key_4", self.session_info["key_reward_amount"])
elif event.key == pygame.K_t:
# print("T down: vacuum on")
- logging.info(";" + str(time.time()) + ";[reward];key_pressed_pump_vacuum")
- self.pump.reward("vacuum", 1)
+ # logging.info(";" + str(time.time()) + ";[reward];key_pressed_pump_vacuum")
+ self.pump.reward("key_vacuum", 1)
elif event.type == pygame.KEYUP:
if event.key == pygame.K_1:
self.left_exit()
@@ -455,27 +478,65 @@ def right_exit(self):
self.interact_list.append((time.time(), "right_exit"))
logging.info(";" + str(time.time()) + ";[action];right_exit")
- def reserved_rx1_pressed(self):
- self.event_list.append("reserved_rx1_pressed")
- self.interact_list.append((time.time(), "reserved_rx1_pressed"))
- logging.info(";" + str(time.time()) + ";[action];reserved_rx1_pressed")
-
- def reserved_rx2_pressed(self):
- self.event_list.append("reserved_rx2_pressed")
- self.interact_list.append((time.time(), "reserved_rx2_pressed"))
- logging.info(";" + str(time.time()) + ";[action];reserved_rx2_pressed")
-
- def reserved_rx1_released(self):
- self.event_list.append("reserved_rx1_released")
- self.interact_list.append((time.time(), "reserved_rx1_released"))
- logging.info(";" + str(time.time()) + ";[action];reserved_rx1_released")
-
- def reserved_rx2_released(self):
- self.event_list.append("reserved_rx2_released")
- self.interact_list.append((time.time(), "reserved_rx2_released"))
- logging.info(";" + str(time.time()) + ";[action];reserved_rx2_released")
-
-
+ # def reserved_rx1_pressed(self):
+ # self.event_list.append("reserved_rx1_pressed")
+ # self.interact_list.append((time.time(), "reserved_rx1_pressed"))
+ # logging.info(";" + str(time.time()) + ";[action];reserved_rx1_pressed")
+ #
+ # def reserved_rx2_pressed(self):
+ # self.event_list.append("reserved_rx2_pressed")
+ # self.interact_list.append((time.time(), "reserved_rx2_pressed"))
+ # logging.info(";" + str(time.time()) + ";[action];reserved_rx2_pressed")
+ #
+ # def reserved_rx1_released(self):
+ # self.event_list.append("reserved_rx1_released")
+ # self.interact_list.append((time.time(), "reserved_rx1_released"))
+ # logging.info(";" + str(time.time()) + ";[action];reserved_rx1_released")
+ #
+ # def reserved_rx2_released(self):
+ # self.event_list.append("reserved_rx2_released")
+ # self.interact_list.append((time.time(), "reserved_rx2_released"))
+ # logging.info(";" + str(time.time()) + ";[action];reserved_rx2_released")
+ def IR_1_entry(self):
+ self.event_list.append("IR_1_entry")
+ logging.info(str(time.time()) + ", IR_1_entry")
+
+ def IR_2_entry(self):
+ self.event_list.append("IR_2_entry")
+ logging.info(str(time.time()) + ", IR_2_entry")
+
+ def IR_3_entry(self):
+ self.event_list.append("IR_3_entry")
+ logging.info(str(time.time()) + ", IR_3_entry")
+
+ def IR_4_entry(self):
+ self.event_list.append("IR_4_entry")
+ logging.info(str(time.time()) + ", IR_4_entry")
+
+ def IR_5_entry(self):
+ self.event_list.append("IR_5_entry")
+ logging.info(str(time.time()) + ", IR_5_entry")
+
+ def IR_1_exit(self):
+ self.event_list.append("IR_1_exit")
+ logging.info(str(time.time()) + ", IR_1_exit")
+
+ def IR_2_exit(self):
+ self.event_list.append("IR_2_exit")
+ # self.cueLED2.off()
+ logging.info(str(time.time()) + ", IR_2_exit")
+
+ def IR_3_exit(self):
+ self.event_list.append("IR_3_exit")
+ logging.info(str(time.time()) + ", IR_3_exit")
+
+ def IR_4_exit(self):
+ self.event_list.append("IR_4_exit")
+ logging.info(str(time.time()) + ", IR_4_exit")
+
+ def IR_5_exit(self):
+ self.event_list.append("IR_5_exit")
+ logging.info(str(time.time()) + ", IR_5_exit")
# this is for the cue LEDs. BoxLED.value is the intensity value (PWM duty cycle, from 0 to 1)
# currently. BoxLED.set_value is the saved intensity value that determines how bright the
@@ -491,7 +552,8 @@ def on(
class Pump(object):
- def __init__(self):
+ def __init__(self, session_info):
+ self.session_info = session_info
self.pump1 = LED(19)
self.pump2 = LED(20)
self.pump3 = LED(21)
@@ -502,44 +564,73 @@ def __init__(self):
# visualization
def reward(self, which_pump, reward_size):
- # coefficient_fit = np.array([8.78674242e-04, 7.33609848e-02, 1.47535000e+00]) # further calibration is needed
- # coefficient_1 = coefficient_fit[-1]
- # coefficient_2 = coefficient_fit[-2]
- # coefficient_3 = coefficient_fit[-3] - reward_size
- tube_fit = 0.11609 # ml/s
- # discriminant = coefficient_2 ** 2 - 4 * coefficient_1 * coefficient_3
- # # find solution, i.e. duration of pulse, by calculating the solution for the quadratic equation
- # solution = np.array([(-coefficient_2 + np.sqrt(discriminant)) / (2 * coefficient_1),
- # (-coefficient_2 - np.sqrt(discriminant)) / (2 * coefficient_1)])
-
- # With two solution, get the positive value
- # solution_positive = solution[(solution > 0).nonzero()[0][0]]
- # round to the second decimal
- # duration = round(solution_positive, 3) * (10**-3)
-
- duration = round((reward_size/1000)/tube_fit, 3)
- duration_vacuum = 0.5
+ # import coefficient from the session_information
+ coefficient_p1 = self.session_info["calibration_coefficient"]['1']
+ coefficient_p2 = self.session_info["calibration_coefficient"]['2']
+ coefficient_p3 = self.session_info["calibration_coefficient"]['3']
+ coefficient_p4 = self.session_info["calibration_coefficient"]['4']
+ duration_air = self.session_info['air_duration']
+ duration_vac = self.session_info["vacuum_duration"]
if which_pump == "1":
+ duration = round((coefficient_p1[0] * (reward_size / 1000) + coefficient_p1[1]), 5) # linear function
self.pump1.blink(duration, 0.1, 1)
self.reward_list.append(("pump1_reward", reward_size))
- logging.info(";" + str(time.time()) + ";[reward];pump1_reward_" + str(reward_size))
+ logging.info(";" + str(time.time()) + ";[reward];pump1_reward(reward_coeff: " + str(coefficient_p1) +
+ ", reward_amount: " + str(reward_size) + "duration: " + str(duration) + ")")
elif which_pump == "2":
+ duration = round((coefficient_p2[0] * (reward_size / 1000) + coefficient_p2[1]), 5) # linear function
self.pump2.blink(duration, 0.1, 1)
self.reward_list.append(("pump2_reward", reward_size))
- logging.info(";" + str(time.time()) + ";[reward];pump2_reward_" + str(reward_size))
+ logging.info(";" + str(time.time()) + ";[reward];pump2_reward(reward_coeff: " + str(coefficient_p2) +
+ ", reward_amount: " + str(reward_size) + "duration: " + str(duration) + ")")
elif which_pump == "3":
+ duration = round((coefficient_p3[0] * (reward_size / 1000) + coefficient_p3[1]), 5) # linear function
self.pump3.blink(duration, 0.1, 1)
self.reward_list.append(("pump3_reward", reward_size))
- logging.info(";" + str(time.time()) + ";[reward];pump3_reward_" + str(reward_size))
+ logging.info(";" + str(time.time()) + ";[reward];pump3_reward(reward_coeff: " + str(coefficient_p3) +
+ ", reward_amount: " + str(reward_size) + "duration: " + str(duration) + ")")
elif which_pump == "4":
+ duration = round((coefficient_p4[0] * (reward_size / 1000) + coefficient_p4[1]), 5) # linear function
self.pump4.blink(duration, 0.1, 1)
self.reward_list.append(("pump4_reward", reward_size))
- logging.info(";" + str(time.time()) + ";[reward];pump4_reward_" + str(reward_size))
+ logging.info(";" + str(time.time()) + ";[reward];pump4_reward(reward_coeff: " + str(coefficient_p4) +
+ ", reward_amount: " + str(reward_size) + "duration: " + str(duration) + ")")
elif which_pump == "air_puff":
- self.pump_air.blink(duration, 0.1, 1)
+ self.pump_air.blink(duration_air, 0.1, 1)
self.reward_list.append(("air_puff", reward_size))
logging.info(";" + str(time.time()) + ";[reward];pump4_reward_" + str(reward_size))
elif which_pump == "vacuum":
- self.pump_vacuum.blink(duration_vacuum, 0.1, 1)
- logging.info(";" + str(time.time()) + ";[reward];pump_vacuum")
\ No newline at end of file
+ self.pump_vacuum.blink(duration_vac, 0.1, 1)
+ logging.info(";" + str(time.time()) + ";[reward];pump_vacuum" + str(duration_vac))
+ elif which_pump == "key_1":
+ duration = round((coefficient_p1[0] * (reward_size / 1000) + coefficient_p1[1]), 5) # linear function
+ self.pump1.blink(duration, 0.1, 1)
+ self.reward_list.append(("pump1_reward", reward_size))
+ logging.info(";" + str(time.time()) + ";[key];pump1_reward(reward_coeff: " + str(coefficient_p1) +
+ ", reward_amount: " + str(reward_size) + "duration: " + str(duration) + ")")
+ elif which_pump == "key_2":
+ duration = round((coefficient_p2[0] * (reward_size / 1000) + coefficient_p2[1]), 5) # linear function
+ self.pump2.blink(duration, 0.1, 1)
+ self.reward_list.append(("pump2_reward", reward_size))
+ logging.info(";" + str(time.time()) + ";[key];pump2_reward(reward_coeff: " + str(coefficient_p2) +
+ ", reward_amount: " + str(reward_size) + "duration: " + str(duration) + ")")
+ elif which_pump == "key_3":
+ duration = round((coefficient_p3[0] * (reward_size / 1000) + coefficient_p3[1]), 5) # linear function
+ self.pump3.blink(duration, 0.1, 1)
+ self.reward_list.append(("pump3_reward", reward_size))
+ logging.info(";" + str(time.time()) + ";[key];pump3_reward(reward_coeff: " + str(coefficient_p3) +
+ ", reward_amount: " + str(reward_size) + "duration: " + str(duration) + ")")
+ elif which_pump == "key_4":
+ duration = round((coefficient_p4[0] * (reward_size / 1000) + coefficient_p4[1]), 5) # linear function
+ self.pump4.blink(duration, 0.1, 1)
+ self.reward_list.append(("pump4_reward", reward_size))
+ logging.info(";" + str(time.time()) + ";[key];pump4_reward(reward_coeff: " + str(coefficient_p4) +
+ ", reward_amount: " + str(reward_size) + "duration: " + str(duration) + ")")
+ elif which_pump == "key_air_puff":
+ self.pump_air.blink(duration_air, 0.1, 1)
+ self.reward_list.append(("air_puff", reward_size))
+ logging.info(";" + str(time.time()) + ";[key];pump4_reward_" + str(reward_size))
+ elif which_pump == "key_vacuum":
+ self.pump_vacuum.blink(duration_vac, 0.1, 1)
+ logging.info(";" + str(time.time()) + ";[key];pump_vacuum" + str(duration_vac))
\ No newline at end of file
diff --git a/camera/Video-Capture-Behavior.py b/essential/camera/Video-Capture-Behavior.py
similarity index 100%
rename from camera/Video-Capture-Behavior.py
rename to essential/camera/Video-Capture-Behavior.py
diff --git a/essential/camera/__init__.py b/essential/camera/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/essential/camera/__init__.py
@@ -0,0 +1 @@
+
diff --git a/camera/camera_sync,record b/essential/camera/camera_sync,record
similarity index 100%
rename from camera/camera_sync,record
rename to essential/camera/camera_sync,record
diff --git a/camera/camera_sync,record.py b/essential/camera/camera_sync,record.py
similarity index 100%
rename from camera/camera_sync,record.py
rename to essential/camera/camera_sync,record.py
diff --git a/camera/readme.md b/essential/camera/readme.md
similarity index 100%
rename from camera/readme.md
rename to essential/camera/readme.md
diff --git a/picamera_library_modified/LICENSE.txt b/essential/picamera_library_modified/LICENSE.txt
similarity index 100%
rename from picamera_library_modified/LICENSE.txt
rename to essential/picamera_library_modified/LICENSE.txt
diff --git a/picamera_library_modified/MANIFEST.in b/essential/picamera_library_modified/MANIFEST.in
similarity index 100%
rename from picamera_library_modified/MANIFEST.in
rename to essential/picamera_library_modified/MANIFEST.in
diff --git a/picamera_library_modified/Makefile b/essential/picamera_library_modified/Makefile
similarity index 100%
rename from picamera_library_modified/Makefile
rename to essential/picamera_library_modified/Makefile
diff --git a/picamera_library_modified/README.rst b/essential/picamera_library_modified/README.rst
similarity index 100%
rename from picamera_library_modified/README.rst
rename to essential/picamera_library_modified/README.rst
diff --git a/picamera_library_modified/build/lib/picamera/__init__.py b/essential/picamera_library_modified/build/lib/picamera/__init__.py
similarity index 100%
rename from picamera_library_modified/build/lib/picamera/__init__.py
rename to essential/picamera_library_modified/build/lib/picamera/__init__.py
diff --git a/picamera_library_modified/build/lib/picamera/array.py b/essential/picamera_library_modified/build/lib/picamera/array.py
similarity index 100%
rename from picamera_library_modified/build/lib/picamera/array.py
rename to essential/picamera_library_modified/build/lib/picamera/array.py
diff --git a/picamera_library_modified/build/lib/picamera/bcm_host.py b/essential/picamera_library_modified/build/lib/picamera/bcm_host.py
similarity index 100%
rename from picamera_library_modified/build/lib/picamera/bcm_host.py
rename to essential/picamera_library_modified/build/lib/picamera/bcm_host.py
diff --git a/picamera_library_modified/build/lib/picamera/camera.py b/essential/picamera_library_modified/build/lib/picamera/camera.py
similarity index 100%
rename from picamera_library_modified/build/lib/picamera/camera.py
rename to essential/picamera_library_modified/build/lib/picamera/camera.py
diff --git a/picamera_library_modified/build/lib/picamera/color.py b/essential/picamera_library_modified/build/lib/picamera/color.py
similarity index 100%
rename from picamera_library_modified/build/lib/picamera/color.py
rename to essential/picamera_library_modified/build/lib/picamera/color.py
diff --git a/picamera_library_modified/build/lib/picamera/display.py b/essential/picamera_library_modified/build/lib/picamera/display.py
similarity index 100%
rename from picamera_library_modified/build/lib/picamera/display.py
rename to essential/picamera_library_modified/build/lib/picamera/display.py
diff --git a/picamera_library_modified/build/lib/picamera/encoders.py b/essential/picamera_library_modified/build/lib/picamera/encoders.py
similarity index 100%
rename from picamera_library_modified/build/lib/picamera/encoders.py
rename to essential/picamera_library_modified/build/lib/picamera/encoders.py
diff --git a/picamera_library_modified/build/lib/picamera/exc.py b/essential/picamera_library_modified/build/lib/picamera/exc.py
similarity index 100%
rename from picamera_library_modified/build/lib/picamera/exc.py
rename to essential/picamera_library_modified/build/lib/picamera/exc.py
diff --git a/picamera_library_modified/build/lib/picamera/frames.py b/essential/picamera_library_modified/build/lib/picamera/frames.py
similarity index 100%
rename from picamera_library_modified/build/lib/picamera/frames.py
rename to essential/picamera_library_modified/build/lib/picamera/frames.py
diff --git a/picamera_library_modified/build/lib/picamera/mmal.py b/essential/picamera_library_modified/build/lib/picamera/mmal.py
similarity index 100%
rename from picamera_library_modified/build/lib/picamera/mmal.py
rename to essential/picamera_library_modified/build/lib/picamera/mmal.py
diff --git a/picamera_library_modified/build/lib/picamera/mmalobj.py b/essential/picamera_library_modified/build/lib/picamera/mmalobj.py
similarity index 100%
rename from picamera_library_modified/build/lib/picamera/mmalobj.py
rename to essential/picamera_library_modified/build/lib/picamera/mmalobj.py
diff --git a/picamera_library_modified/build/lib/picamera/renderers.py b/essential/picamera_library_modified/build/lib/picamera/renderers.py
similarity index 100%
rename from picamera_library_modified/build/lib/picamera/renderers.py
rename to essential/picamera_library_modified/build/lib/picamera/renderers.py
diff --git a/picamera_library_modified/build/lib/picamera/streams.py b/essential/picamera_library_modified/build/lib/picamera/streams.py
similarity index 100%
rename from picamera_library_modified/build/lib/picamera/streams.py
rename to essential/picamera_library_modified/build/lib/picamera/streams.py
diff --git a/picamera_library_modified/coverage.cfg b/essential/picamera_library_modified/coverage.cfg
similarity index 100%
rename from picamera_library_modified/coverage.cfg
rename to essential/picamera_library_modified/coverage.cfg
diff --git a/picamera_library_modified/debian/changelog b/essential/picamera_library_modified/debian/changelog
similarity index 100%
rename from picamera_library_modified/debian/changelog
rename to essential/picamera_library_modified/debian/changelog
diff --git a/picamera_library_modified/debian/clean b/essential/picamera_library_modified/debian/clean
similarity index 100%
rename from picamera_library_modified/debian/clean
rename to essential/picamera_library_modified/debian/clean
diff --git a/picamera_library_modified/debian/compat b/essential/picamera_library_modified/debian/compat
similarity index 100%
rename from picamera_library_modified/debian/compat
rename to essential/picamera_library_modified/debian/compat
diff --git a/picamera_library_modified/debian/control b/essential/picamera_library_modified/debian/control
similarity index 100%
rename from picamera_library_modified/debian/control
rename to essential/picamera_library_modified/debian/control
diff --git a/picamera_library_modified/debian/copyright b/essential/picamera_library_modified/debian/copyright
similarity index 100%
rename from picamera_library_modified/debian/copyright
rename to essential/picamera_library_modified/debian/copyright
diff --git a/picamera_library_modified/debian/docs b/essential/picamera_library_modified/debian/docs
similarity index 100%
rename from picamera_library_modified/debian/docs
rename to essential/picamera_library_modified/debian/docs
diff --git a/picamera_library_modified/debian/python-picamera-docs.doc-base b/essential/picamera_library_modified/debian/python-picamera-docs.doc-base
similarity index 100%
rename from picamera_library_modified/debian/python-picamera-docs.doc-base
rename to essential/picamera_library_modified/debian/python-picamera-docs.doc-base
diff --git a/picamera_library_modified/debian/python-picamera-docs.docs b/essential/picamera_library_modified/debian/python-picamera-docs.docs
similarity index 100%
rename from picamera_library_modified/debian/python-picamera-docs.docs
rename to essential/picamera_library_modified/debian/python-picamera-docs.docs
diff --git a/picamera_library_modified/debian/rules b/essential/picamera_library_modified/debian/rules
similarity index 100%
rename from picamera_library_modified/debian/rules
rename to essential/picamera_library_modified/debian/rules
diff --git a/picamera_library_modified/debian/source/format b/essential/picamera_library_modified/debian/source/format
similarity index 100%
rename from picamera_library_modified/debian/source/format
rename to essential/picamera_library_modified/debian/source/format
diff --git a/picamera_library_modified/debian/source/options b/essential/picamera_library_modified/debian/source/options
similarity index 100%
rename from picamera_library_modified/debian/source/options
rename to essential/picamera_library_modified/debian/source/options
diff --git a/picamera_library_modified/dist/picamera-1.13-py3.7.egg b/essential/picamera_library_modified/dist/picamera-1.13-py3.7.egg
similarity index 100%
rename from picamera_library_modified/dist/picamera-1.13-py3.7.egg
rename to essential/picamera_library_modified/dist/picamera-1.13-py3.7.egg
diff --git a/picamera_library_modified/docs/Makefile b/essential/picamera_library_modified/docs/Makefile
similarity index 100%
rename from picamera_library_modified/docs/Makefile
rename to essential/picamera_library_modified/docs/Makefile
diff --git a/picamera_library_modified/docs/_static/style_override.css b/essential/picamera_library_modified/docs/_static/style_override.css
similarity index 100%
rename from picamera_library_modified/docs/_static/style_override.css
rename to essential/picamera_library_modified/docs/_static/style_override.css
diff --git a/picamera_library_modified/docs/api_array.rst b/essential/picamera_library_modified/docs/api_array.rst
similarity index 100%
rename from picamera_library_modified/docs/api_array.rst
rename to essential/picamera_library_modified/docs/api_array.rst
diff --git a/picamera_library_modified/docs/api_camera.rst b/essential/picamera_library_modified/docs/api_camera.rst
similarity index 100%
rename from picamera_library_modified/docs/api_camera.rst
rename to essential/picamera_library_modified/docs/api_camera.rst
diff --git a/picamera_library_modified/docs/api_color.rst b/essential/picamera_library_modified/docs/api_color.rst
similarity index 100%
rename from picamera_library_modified/docs/api_color.rst
rename to essential/picamera_library_modified/docs/api_color.rst
diff --git a/picamera_library_modified/docs/api_encoders.rst b/essential/picamera_library_modified/docs/api_encoders.rst
similarity index 100%
rename from picamera_library_modified/docs/api_encoders.rst
rename to essential/picamera_library_modified/docs/api_encoders.rst
diff --git a/picamera_library_modified/docs/api_exc.rst b/essential/picamera_library_modified/docs/api_exc.rst
similarity index 100%
rename from picamera_library_modified/docs/api_exc.rst
rename to essential/picamera_library_modified/docs/api_exc.rst
diff --git a/picamera_library_modified/docs/api_mmalobj.rst b/essential/picamera_library_modified/docs/api_mmalobj.rst
similarity index 100%
rename from picamera_library_modified/docs/api_mmalobj.rst
rename to essential/picamera_library_modified/docs/api_mmalobj.rst
diff --git a/picamera_library_modified/docs/api_renderers.rst b/essential/picamera_library_modified/docs/api_renderers.rst
similarity index 100%
rename from picamera_library_modified/docs/api_renderers.rst
rename to essential/picamera_library_modified/docs/api_renderers.rst
diff --git a/picamera_library_modified/docs/api_streams.rst b/essential/picamera_library_modified/docs/api_streams.rst
similarity index 100%
rename from picamera_library_modified/docs/api_streams.rst
rename to essential/picamera_library_modified/docs/api_streams.rst
diff --git a/picamera_library_modified/docs/changelog.rst b/essential/picamera_library_modified/docs/changelog.rst
similarity index 100%
rename from picamera_library_modified/docs/changelog.rst
rename to essential/picamera_library_modified/docs/changelog.rst
diff --git a/picamera_library_modified/docs/conf.py b/essential/picamera_library_modified/docs/conf.py
similarity index 100%
rename from picamera_library_modified/docs/conf.py
rename to essential/picamera_library_modified/docs/conf.py
diff --git a/picamera_library_modified/docs/deprecated.rst b/essential/picamera_library_modified/docs/deprecated.rst
similarity index 100%
rename from picamera_library_modified/docs/deprecated.rst
rename to essential/picamera_library_modified/docs/deprecated.rst
diff --git a/picamera_library_modified/docs/development.rst b/essential/picamera_library_modified/docs/development.rst
similarity index 100%
rename from picamera_library_modified/docs/development.rst
rename to essential/picamera_library_modified/docs/development.rst
diff --git a/picamera_library_modified/docs/encoder_classes.dot b/essential/picamera_library_modified/docs/encoder_classes.dot
similarity index 100%
rename from picamera_library_modified/docs/encoder_classes.dot
rename to essential/picamera_library_modified/docs/encoder_classes.dot
diff --git a/picamera_library_modified/docs/examples/array_capture_py2.py b/essential/picamera_library_modified/docs/examples/array_capture_py2.py
similarity index 100%
rename from picamera_library_modified/docs/examples/array_capture_py2.py
rename to essential/picamera_library_modified/docs/examples/array_capture_py2.py
diff --git a/picamera_library_modified/docs/examples/array_capture_py3.py b/essential/picamera_library_modified/docs/examples/array_capture_py3.py
similarity index 100%
rename from picamera_library_modified/docs/examples/array_capture_py3.py
rename to essential/picamera_library_modified/docs/examples/array_capture_py3.py
diff --git a/picamera_library_modified/docs/examples/bayer_array.py b/essential/picamera_library_modified/docs/examples/bayer_array.py
similarity index 100%
rename from picamera_library_modified/docs/examples/bayer_array.py
rename to essential/picamera_library_modified/docs/examples/bayer_array.py
diff --git a/picamera_library_modified/docs/examples/bayer_data.py b/essential/picamera_library_modified/docs/examples/bayer_data.py
similarity index 100%
rename from picamera_library_modified/docs/examples/bayer_data.py
rename to essential/picamera_library_modified/docs/examples/bayer_data.py
diff --git a/picamera_library_modified/docs/examples/capture_client.py b/essential/picamera_library_modified/docs/examples/capture_client.py
similarity index 100%
rename from picamera_library_modified/docs/examples/capture_client.py
rename to essential/picamera_library_modified/docs/examples/capture_client.py
diff --git a/picamera_library_modified/docs/examples/capture_server.py b/essential/picamera_library_modified/docs/examples/capture_server.py
similarity index 100%
rename from picamera_library_modified/docs/examples/capture_server.py
rename to essential/picamera_library_modified/docs/examples/capture_server.py
diff --git a/picamera_library_modified/docs/examples/circular_record1.py b/essential/picamera_library_modified/docs/examples/circular_record1.py
similarity index 100%
rename from picamera_library_modified/docs/examples/circular_record1.py
rename to essential/picamera_library_modified/docs/examples/circular_record1.py
diff --git a/picamera_library_modified/docs/examples/circular_record2.py b/essential/picamera_library_modified/docs/examples/circular_record2.py
similarity index 100%
rename from picamera_library_modified/docs/examples/circular_record2.py
rename to essential/picamera_library_modified/docs/examples/circular_record2.py
diff --git a/picamera_library_modified/docs/examples/color_detect.py b/essential/picamera_library_modified/docs/examples/color_detect.py
similarity index 100%
rename from picamera_library_modified/docs/examples/color_detect.py
rename to essential/picamera_library_modified/docs/examples/color_detect.py
diff --git a/picamera_library_modified/docs/examples/consistent_capture.py b/essential/picamera_library_modified/docs/examples/consistent_capture.py
similarity index 100%
rename from picamera_library_modified/docs/examples/consistent_capture.py
rename to essential/picamera_library_modified/docs/examples/consistent_capture.py
diff --git a/picamera_library_modified/docs/examples/custom_encoders.py b/essential/picamera_library_modified/docs/examples/custom_encoders.py
similarity index 100%
rename from picamera_library_modified/docs/examples/custom_encoders.py
rename to essential/picamera_library_modified/docs/examples/custom_encoders.py
diff --git a/picamera_library_modified/docs/examples/custom_outputs_count.py b/essential/picamera_library_modified/docs/examples/custom_outputs_count.py
similarity index 100%
rename from picamera_library_modified/docs/examples/custom_outputs_count.py
rename to essential/picamera_library_modified/docs/examples/custom_outputs_count.py
diff --git a/picamera_library_modified/docs/examples/custom_outputs_motion_analysis.py b/essential/picamera_library_modified/docs/examples/custom_outputs_motion_analysis.py
similarity index 100%
rename from picamera_library_modified/docs/examples/custom_outputs_motion_analysis.py
rename to essential/picamera_library_modified/docs/examples/custom_outputs_motion_analysis.py
diff --git a/picamera_library_modified/docs/examples/custom_outputs_motion_detector.py b/essential/picamera_library_modified/docs/examples/custom_outputs_motion_detector.py
similarity index 100%
rename from picamera_library_modified/docs/examples/custom_outputs_motion_detector.py
rename to essential/picamera_library_modified/docs/examples/custom_outputs_motion_detector.py
diff --git a/picamera_library_modified/docs/examples/file_capture.py b/essential/picamera_library_modified/docs/examples/file_capture.py
similarity index 100%
rename from picamera_library_modified/docs/examples/file_capture.py
rename to essential/picamera_library_modified/docs/examples/file_capture.py
diff --git a/picamera_library_modified/docs/examples/file_record.py b/essential/picamera_library_modified/docs/examples/file_record.py
similarity index 100%
rename from picamera_library_modified/docs/examples/file_record.py
rename to essential/picamera_library_modified/docs/examples/file_record.py
diff --git a/picamera_library_modified/docs/examples/gesture_detect.py b/essential/picamera_library_modified/docs/examples/gesture_detect.py
similarity index 100%
rename from picamera_library_modified/docs/examples/gesture_detect.py
rename to essential/picamera_library_modified/docs/examples/gesture_detect.py
diff --git a/picamera_library_modified/docs/examples/image_overlay_array.py b/essential/picamera_library_modified/docs/examples/image_overlay_array.py
similarity index 100%
rename from picamera_library_modified/docs/examples/image_overlay_array.py
rename to essential/picamera_library_modified/docs/examples/image_overlay_array.py
diff --git a/picamera_library_modified/docs/examples/image_overlay_file.py b/essential/picamera_library_modified/docs/examples/image_overlay_file.py
similarity index 100%
rename from picamera_library_modified/docs/examples/image_overlay_file.py
rename to essential/picamera_library_modified/docs/examples/image_overlay_file.py
diff --git a/picamera_library_modified/docs/examples/led_control.py b/essential/picamera_library_modified/docs/examples/led_control.py
similarity index 100%
rename from picamera_library_modified/docs/examples/led_control.py
rename to essential/picamera_library_modified/docs/examples/led_control.py
diff --git a/picamera_library_modified/docs/examples/mmal_clock_splitter.py b/essential/picamera_library_modified/docs/examples/mmal_clock_splitter.py
similarity index 100%
rename from picamera_library_modified/docs/examples/mmal_clock_splitter.py
rename to essential/picamera_library_modified/docs/examples/mmal_clock_splitter.py
diff --git a/picamera_library_modified/docs/examples/mmal_crosshair.py b/essential/picamera_library_modified/docs/examples/mmal_crosshair.py
similarity index 100%
rename from picamera_library_modified/docs/examples/mmal_crosshair.py
rename to essential/picamera_library_modified/docs/examples/mmal_crosshair.py
diff --git a/picamera_library_modified/docs/examples/motion_data1.py b/essential/picamera_library_modified/docs/examples/motion_data1.py
similarity index 100%
rename from picamera_library_modified/docs/examples/motion_data1.py
rename to essential/picamera_library_modified/docs/examples/motion_data1.py
diff --git a/picamera_library_modified/docs/examples/motion_data2.py b/essential/picamera_library_modified/docs/examples/motion_data2.py
similarity index 100%
rename from picamera_library_modified/docs/examples/motion_data2.py
rename to essential/picamera_library_modified/docs/examples/motion_data2.py
diff --git a/picamera_library_modified/docs/examples/motion_data3.py b/essential/picamera_library_modified/docs/examples/motion_data3.py
similarity index 100%
rename from picamera_library_modified/docs/examples/motion_data3.py
rename to essential/picamera_library_modified/docs/examples/motion_data3.py
diff --git a/picamera_library_modified/docs/examples/motion_data4.py b/essential/picamera_library_modified/docs/examples/motion_data4.py
similarity index 100%
rename from picamera_library_modified/docs/examples/motion_data4.py
rename to essential/picamera_library_modified/docs/examples/motion_data4.py
diff --git a/picamera_library_modified/docs/examples/multi_res_record.py b/essential/picamera_library_modified/docs/examples/multi_res_record.py
similarity index 100%
rename from picamera_library_modified/docs/examples/multi_res_record.py
rename to essential/picamera_library_modified/docs/examples/multi_res_record.py
diff --git a/picamera_library_modified/docs/examples/multiproc_camera.py b/essential/picamera_library_modified/docs/examples/multiproc_camera.py
similarity index 100%
rename from picamera_library_modified/docs/examples/multiproc_camera.py
rename to essential/picamera_library_modified/docs/examples/multiproc_camera.py
diff --git a/picamera_library_modified/docs/examples/night_capture.py b/essential/picamera_library_modified/docs/examples/night_capture.py
similarity index 100%
rename from picamera_library_modified/docs/examples/night_capture.py
rename to essential/picamera_library_modified/docs/examples/night_capture.py
diff --git a/picamera_library_modified/docs/examples/opencv_capture.py b/essential/picamera_library_modified/docs/examples/opencv_capture.py
similarity index 100%
rename from picamera_library_modified/docs/examples/opencv_capture.py
rename to essential/picamera_library_modified/docs/examples/opencv_capture.py
diff --git a/picamera_library_modified/docs/examples/pil_capture.py b/essential/picamera_library_modified/docs/examples/pil_capture.py
similarity index 100%
rename from picamera_library_modified/docs/examples/pil_capture.py
rename to essential/picamera_library_modified/docs/examples/pil_capture.py
diff --git a/picamera_library_modified/docs/examples/rapid_capture_generator.py b/essential/picamera_library_modified/docs/examples/rapid_capture_generator.py
similarity index 100%
rename from picamera_library_modified/docs/examples/rapid_capture_generator.py
rename to essential/picamera_library_modified/docs/examples/rapid_capture_generator.py
diff --git a/picamera_library_modified/docs/examples/rapid_capture_mjpeg.py b/essential/picamera_library_modified/docs/examples/rapid_capture_mjpeg.py
similarity index 100%
rename from picamera_library_modified/docs/examples/rapid_capture_mjpeg.py
rename to essential/picamera_library_modified/docs/examples/rapid_capture_mjpeg.py
diff --git a/picamera_library_modified/docs/examples/rapid_capture_sequence.py b/essential/picamera_library_modified/docs/examples/rapid_capture_sequence.py
similarity index 100%
rename from picamera_library_modified/docs/examples/rapid_capture_sequence.py
rename to essential/picamera_library_modified/docs/examples/rapid_capture_sequence.py
diff --git a/picamera_library_modified/docs/examples/rapid_capture_threading.py b/essential/picamera_library_modified/docs/examples/rapid_capture_threading.py
similarity index 100%
rename from picamera_library_modified/docs/examples/rapid_capture_threading.py
rename to essential/picamera_library_modified/docs/examples/rapid_capture_threading.py
diff --git a/picamera_library_modified/docs/examples/rapid_capture_yield.py b/essential/picamera_library_modified/docs/examples/rapid_capture_yield.py
similarity index 100%
rename from picamera_library_modified/docs/examples/rapid_capture_yield.py
rename to essential/picamera_library_modified/docs/examples/rapid_capture_yield.py
diff --git a/picamera_library_modified/docs/examples/rapid_streaming.py b/essential/picamera_library_modified/docs/examples/rapid_streaming.py
similarity index 100%
rename from picamera_library_modified/docs/examples/rapid_streaming.py
rename to essential/picamera_library_modified/docs/examples/rapid_streaming.py
diff --git a/picamera_library_modified/docs/examples/rapid_streaming_mjpeg.py b/essential/picamera_library_modified/docs/examples/rapid_streaming_mjpeg.py
similarity index 100%
rename from picamera_library_modified/docs/examples/rapid_streaming_mjpeg.py
rename to essential/picamera_library_modified/docs/examples/rapid_streaming_mjpeg.py
diff --git a/picamera_library_modified/docs/examples/record_and_capture.py b/essential/picamera_library_modified/docs/examples/record_and_capture.py
similarity index 100%
rename from picamera_library_modified/docs/examples/record_and_capture.py
rename to essential/picamera_library_modified/docs/examples/record_and_capture.py
diff --git a/picamera_library_modified/docs/examples/record_client.py b/essential/picamera_library_modified/docs/examples/record_client.py
similarity index 100%
rename from picamera_library_modified/docs/examples/record_client.py
rename to essential/picamera_library_modified/docs/examples/record_client.py
diff --git a/picamera_library_modified/docs/examples/record_sequence.py b/essential/picamera_library_modified/docs/examples/record_sequence.py
similarity index 100%
rename from picamera_library_modified/docs/examples/record_sequence.py
rename to essential/picamera_library_modified/docs/examples/record_sequence.py
diff --git a/picamera_library_modified/docs/examples/record_server.py b/essential/picamera_library_modified/docs/examples/record_server.py
similarity index 100%
rename from picamera_library_modified/docs/examples/record_server.py
rename to essential/picamera_library_modified/docs/examples/record_server.py
diff --git a/picamera_library_modified/docs/examples/record_server_pi.py b/essential/picamera_library_modified/docs/examples/record_server_pi.py
similarity index 100%
rename from picamera_library_modified/docs/examples/record_server_pi.py
rename to essential/picamera_library_modified/docs/examples/record_server_pi.py
diff --git a/picamera_library_modified/docs/examples/resize_capture.py b/essential/picamera_library_modified/docs/examples/resize_capture.py
similarity index 100%
rename from picamera_library_modified/docs/examples/resize_capture.py
rename to essential/picamera_library_modified/docs/examples/resize_capture.py
diff --git a/picamera_library_modified/docs/examples/rgb_capture1.py b/essential/picamera_library_modified/docs/examples/rgb_capture1.py
similarity index 100%
rename from picamera_library_modified/docs/examples/rgb_capture1.py
rename to essential/picamera_library_modified/docs/examples/rgb_capture1.py
diff --git a/picamera_library_modified/docs/examples/rgb_capture2.py b/essential/picamera_library_modified/docs/examples/rgb_capture2.py
similarity index 100%
rename from picamera_library_modified/docs/examples/rgb_capture2.py
rename to essential/picamera_library_modified/docs/examples/rgb_capture2.py
diff --git a/picamera_library_modified/docs/examples/split_record.py b/essential/picamera_library_modified/docs/examples/split_record.py
similarity index 100%
rename from picamera_library_modified/docs/examples/split_record.py
rename to essential/picamera_library_modified/docs/examples/split_record.py
diff --git a/picamera_library_modified/docs/examples/stream_capture.py b/essential/picamera_library_modified/docs/examples/stream_capture.py
similarity index 100%
rename from picamera_library_modified/docs/examples/stream_capture.py
rename to essential/picamera_library_modified/docs/examples/stream_capture.py
diff --git a/picamera_library_modified/docs/examples/stream_capture_close.py b/essential/picamera_library_modified/docs/examples/stream_capture_close.py
similarity index 100%
rename from picamera_library_modified/docs/examples/stream_capture_close.py
rename to essential/picamera_library_modified/docs/examples/stream_capture_close.py
diff --git a/picamera_library_modified/docs/examples/stream_record.py b/essential/picamera_library_modified/docs/examples/stream_record.py
similarity index 100%
rename from picamera_library_modified/docs/examples/stream_record.py
rename to essential/picamera_library_modified/docs/examples/stream_record.py
diff --git a/picamera_library_modified/docs/examples/text_overlay.py b/essential/picamera_library_modified/docs/examples/text_overlay.py
similarity index 100%
rename from picamera_library_modified/docs/examples/text_overlay.py
rename to essential/picamera_library_modified/docs/examples/text_overlay.py
diff --git a/picamera_library_modified/docs/examples/text_overlay_scroll.py b/essential/picamera_library_modified/docs/examples/text_overlay_scroll.py
similarity index 100%
rename from picamera_library_modified/docs/examples/text_overlay_scroll.py
rename to essential/picamera_library_modified/docs/examples/text_overlay_scroll.py
diff --git a/picamera_library_modified/docs/examples/text_overlay_timestamp.py b/essential/picamera_library_modified/docs/examples/text_overlay_timestamp.py
similarity index 100%
rename from picamera_library_modified/docs/examples/text_overlay_timestamp.py
rename to essential/picamera_library_modified/docs/examples/text_overlay_timestamp.py
diff --git a/picamera_library_modified/docs/examples/timelapse1.py b/essential/picamera_library_modified/docs/examples/timelapse1.py
similarity index 100%
rename from picamera_library_modified/docs/examples/timelapse1.py
rename to essential/picamera_library_modified/docs/examples/timelapse1.py
diff --git a/picamera_library_modified/docs/examples/timelapse2.py b/essential/picamera_library_modified/docs/examples/timelapse2.py
similarity index 100%
rename from picamera_library_modified/docs/examples/timelapse2.py
rename to essential/picamera_library_modified/docs/examples/timelapse2.py
diff --git a/picamera_library_modified/docs/examples/web_streaming.py b/essential/picamera_library_modified/docs/examples/web_streaming.py
similarity index 100%
rename from picamera_library_modified/docs/examples/web_streaming.py
rename to essential/picamera_library_modified/docs/examples/web_streaming.py
diff --git a/picamera_library_modified/docs/examples/weird_outputs.py b/essential/picamera_library_modified/docs/examples/weird_outputs.py
similarity index 100%
rename from picamera_library_modified/docs/examples/weird_outputs.py
rename to essential/picamera_library_modified/docs/examples/weird_outputs.py
diff --git a/picamera_library_modified/docs/examples/yuv_capture1.py b/essential/picamera_library_modified/docs/examples/yuv_capture1.py
similarity index 100%
rename from picamera_library_modified/docs/examples/yuv_capture1.py
rename to essential/picamera_library_modified/docs/examples/yuv_capture1.py
diff --git a/picamera_library_modified/docs/examples/yuv_capture2.py b/essential/picamera_library_modified/docs/examples/yuv_capture2.py
similarity index 100%
rename from picamera_library_modified/docs/examples/yuv_capture2.py
rename to essential/picamera_library_modified/docs/examples/yuv_capture2.py
diff --git a/picamera_library_modified/docs/examples/yuv_capture3.py b/essential/picamera_library_modified/docs/examples/yuv_capture3.py
similarity index 100%
rename from picamera_library_modified/docs/examples/yuv_capture3.py
rename to essential/picamera_library_modified/docs/examples/yuv_capture3.py
diff --git a/picamera_library_modified/docs/examples/yuv_capture4.py b/essential/picamera_library_modified/docs/examples/yuv_capture4.py
similarity index 100%
rename from picamera_library_modified/docs/examples/yuv_capture4.py
rename to essential/picamera_library_modified/docs/examples/yuv_capture4.py
diff --git a/picamera_library_modified/docs/faq.rst b/essential/picamera_library_modified/docs/faq.rst
similarity index 100%
rename from picamera_library_modified/docs/faq.rst
rename to essential/picamera_library_modified/docs/faq.rst
diff --git a/picamera_library_modified/docs/fov.rst b/essential/picamera_library_modified/docs/fov.rst
similarity index 100%
rename from picamera_library_modified/docs/fov.rst
rename to essential/picamera_library_modified/docs/fov.rst
diff --git a/picamera_library_modified/docs/images/bayer_bytes.pdf b/essential/picamera_library_modified/docs/images/bayer_bytes.pdf
similarity index 100%
rename from picamera_library_modified/docs/images/bayer_bytes.pdf
rename to essential/picamera_library_modified/docs/images/bayer_bytes.pdf
diff --git a/picamera_library_modified/docs/images/bayer_bytes.png b/essential/picamera_library_modified/docs/images/bayer_bytes.png
similarity index 100%
rename from picamera_library_modified/docs/images/bayer_bytes.png
rename to essential/picamera_library_modified/docs/images/bayer_bytes.png
diff --git a/picamera_library_modified/docs/images/bayer_bytes.svg b/essential/picamera_library_modified/docs/images/bayer_bytes.svg
similarity index 100%
rename from picamera_library_modified/docs/images/bayer_bytes.svg
rename to essential/picamera_library_modified/docs/images/bayer_bytes.svg
diff --git a/picamera_library_modified/docs/images/bayer_pattern.pdf b/essential/picamera_library_modified/docs/images/bayer_pattern.pdf
similarity index 100%
rename from picamera_library_modified/docs/images/bayer_pattern.pdf
rename to essential/picamera_library_modified/docs/images/bayer_pattern.pdf
diff --git a/picamera_library_modified/docs/images/bayer_pattern.png b/essential/picamera_library_modified/docs/images/bayer_pattern.png
similarity index 100%
rename from picamera_library_modified/docs/images/bayer_pattern.png
rename to essential/picamera_library_modified/docs/images/bayer_pattern.png
diff --git a/picamera_library_modified/docs/images/bayer_pattern.svg b/essential/picamera_library_modified/docs/images/bayer_pattern.svg
similarity index 100%
rename from picamera_library_modified/docs/images/bayer_pattern.svg
rename to essential/picamera_library_modified/docs/images/bayer_pattern.svg
diff --git a/picamera_library_modified/docs/images/camera_architecture.pdf b/essential/picamera_library_modified/docs/images/camera_architecture.pdf
similarity index 100%
rename from picamera_library_modified/docs/images/camera_architecture.pdf
rename to essential/picamera_library_modified/docs/images/camera_architecture.pdf
diff --git a/picamera_library_modified/docs/images/camera_architecture.png b/essential/picamera_library_modified/docs/images/camera_architecture.png
similarity index 100%
rename from picamera_library_modified/docs/images/camera_architecture.png
rename to essential/picamera_library_modified/docs/images/camera_architecture.png
diff --git a/picamera_library_modified/docs/images/camera_architecture.svg b/essential/picamera_library_modified/docs/images/camera_architecture.svg
similarity index 100%
rename from picamera_library_modified/docs/images/camera_architecture.svg
rename to essential/picamera_library_modified/docs/images/camera_architecture.svg
diff --git a/picamera_library_modified/docs/images/camera_layout.pdf b/essential/picamera_library_modified/docs/images/camera_layout.pdf
similarity index 100%
rename from picamera_library_modified/docs/images/camera_layout.pdf
rename to essential/picamera_library_modified/docs/images/camera_layout.pdf
diff --git a/picamera_library_modified/docs/images/camera_layout.png b/essential/picamera_library_modified/docs/images/camera_layout.png
similarity index 100%
rename from picamera_library_modified/docs/images/camera_layout.png
rename to essential/picamera_library_modified/docs/images/camera_layout.png
diff --git a/picamera_library_modified/docs/images/camera_layout.svg b/essential/picamera_library_modified/docs/images/camera_layout.svg
similarity index 100%
rename from picamera_library_modified/docs/images/camera_layout.svg
rename to essential/picamera_library_modified/docs/images/camera_layout.svg
diff --git a/picamera_library_modified/docs/images/enable_camera.png b/essential/picamera_library_modified/docs/images/enable_camera.png
similarity index 100%
rename from picamera_library_modified/docs/images/enable_camera.png
rename to essential/picamera_library_modified/docs/images/enable_camera.png
diff --git a/picamera_library_modified/docs/images/encoder_classes.pdf b/essential/picamera_library_modified/docs/images/encoder_classes.pdf
similarity index 100%
rename from picamera_library_modified/docs/images/encoder_classes.pdf
rename to essential/picamera_library_modified/docs/images/encoder_classes.pdf
diff --git a/picamera_library_modified/docs/images/encoder_classes.png b/essential/picamera_library_modified/docs/images/encoder_classes.png
similarity index 100%
rename from picamera_library_modified/docs/images/encoder_classes.png
rename to essential/picamera_library_modified/docs/images/encoder_classes.png
diff --git a/picamera_library_modified/docs/images/encoder_classes.svg b/essential/picamera_library_modified/docs/images/encoder_classes.svg
similarity index 100%
rename from picamera_library_modified/docs/images/encoder_classes.svg
rename to essential/picamera_library_modified/docs/images/encoder_classes.svg
diff --git a/picamera_library_modified/docs/images/good_connection.jpg b/essential/picamera_library_modified/docs/images/good_connection.jpg
similarity index 100%
rename from picamera_library_modified/docs/images/good_connection.jpg
rename to essential/picamera_library_modified/docs/images/good_connection.jpg
diff --git a/picamera_library_modified/docs/images/good_connection.xcf b/essential/picamera_library_modified/docs/images/good_connection.xcf
similarity index 100%
rename from picamera_library_modified/docs/images/good_connection.xcf
rename to essential/picamera_library_modified/docs/images/good_connection.xcf
diff --git a/picamera_library_modified/docs/images/gpu_architecture.pdf b/essential/picamera_library_modified/docs/images/gpu_architecture.pdf
similarity index 100%
rename from picamera_library_modified/docs/images/gpu_architecture.pdf
rename to essential/picamera_library_modified/docs/images/gpu_architecture.pdf
diff --git a/picamera_library_modified/docs/images/gpu_architecture.png b/essential/picamera_library_modified/docs/images/gpu_architecture.png
similarity index 100%
rename from picamera_library_modified/docs/images/gpu_architecture.png
rename to essential/picamera_library_modified/docs/images/gpu_architecture.png
diff --git a/picamera_library_modified/docs/images/gpu_architecture.svg b/essential/picamera_library_modified/docs/images/gpu_architecture.svg
similarity index 100%
rename from picamera_library_modified/docs/images/gpu_architecture.svg
rename to essential/picamera_library_modified/docs/images/gpu_architecture.svg
diff --git a/picamera_library_modified/docs/images/image_protocol.pdf b/essential/picamera_library_modified/docs/images/image_protocol.pdf
similarity index 100%
rename from picamera_library_modified/docs/images/image_protocol.pdf
rename to essential/picamera_library_modified/docs/images/image_protocol.pdf
diff --git a/picamera_library_modified/docs/images/image_protocol.png b/essential/picamera_library_modified/docs/images/image_protocol.png
similarity index 100%
rename from picamera_library_modified/docs/images/image_protocol.png
rename to essential/picamera_library_modified/docs/images/image_protocol.png
diff --git a/picamera_library_modified/docs/images/image_protocol.svg b/essential/picamera_library_modified/docs/images/image_protocol.svg
similarity index 100%
rename from picamera_library_modified/docs/images/image_protocol.svg
rename to essential/picamera_library_modified/docs/images/image_protocol.svg
diff --git a/picamera_library_modified/docs/images/jpeg_capture_pipeline.dot b/essential/picamera_library_modified/docs/images/jpeg_capture_pipeline.dot
similarity index 100%
rename from picamera_library_modified/docs/images/jpeg_capture_pipeline.dot
rename to essential/picamera_library_modified/docs/images/jpeg_capture_pipeline.dot
diff --git a/picamera_library_modified/docs/images/jpeg_capture_pipeline.pdf b/essential/picamera_library_modified/docs/images/jpeg_capture_pipeline.pdf
similarity index 100%
rename from picamera_library_modified/docs/images/jpeg_capture_pipeline.pdf
rename to essential/picamera_library_modified/docs/images/jpeg_capture_pipeline.pdf
diff --git a/picamera_library_modified/docs/images/jpeg_capture_pipeline.png b/essential/picamera_library_modified/docs/images/jpeg_capture_pipeline.png
similarity index 100%
rename from picamera_library_modified/docs/images/jpeg_capture_pipeline.png
rename to essential/picamera_library_modified/docs/images/jpeg_capture_pipeline.png
diff --git a/picamera_library_modified/docs/images/jpeg_capture_pipeline.svg b/essential/picamera_library_modified/docs/images/jpeg_capture_pipeline.svg
similarity index 100%
rename from picamera_library_modified/docs/images/jpeg_capture_pipeline.svg
rename to essential/picamera_library_modified/docs/images/jpeg_capture_pipeline.svg
diff --git a/picamera_library_modified/docs/images/jpeg_encode_pipeline.dot b/essential/picamera_library_modified/docs/images/jpeg_encode_pipeline.dot
similarity index 100%
rename from picamera_library_modified/docs/images/jpeg_encode_pipeline.dot
rename to essential/picamera_library_modified/docs/images/jpeg_encode_pipeline.dot
diff --git a/picamera_library_modified/docs/images/jpeg_encode_pipeline.pdf b/essential/picamera_library_modified/docs/images/jpeg_encode_pipeline.pdf
similarity index 100%
rename from picamera_library_modified/docs/images/jpeg_encode_pipeline.pdf
rename to essential/picamera_library_modified/docs/images/jpeg_encode_pipeline.pdf
diff --git a/picamera_library_modified/docs/images/jpeg_encode_pipeline.png b/essential/picamera_library_modified/docs/images/jpeg_encode_pipeline.png
similarity index 100%
rename from picamera_library_modified/docs/images/jpeg_encode_pipeline.png
rename to essential/picamera_library_modified/docs/images/jpeg_encode_pipeline.png
diff --git a/picamera_library_modified/docs/images/jpeg_encode_pipeline.svg b/essential/picamera_library_modified/docs/images/jpeg_encode_pipeline.svg
similarity index 100%
rename from picamera_library_modified/docs/images/jpeg_encode_pipeline.svg
rename to essential/picamera_library_modified/docs/images/jpeg_encode_pipeline.svg
diff --git a/picamera_library_modified/docs/images/pi_zero_assembled.jpg b/essential/picamera_library_modified/docs/images/pi_zero_assembled.jpg
similarity index 100%
rename from picamera_library_modified/docs/images/pi_zero_assembled.jpg
rename to essential/picamera_library_modified/docs/images/pi_zero_assembled.jpg
diff --git a/picamera_library_modified/docs/images/pi_zero_pieces.jpg b/essential/picamera_library_modified/docs/images/pi_zero_pieces.jpg
similarity index 100%
rename from picamera_library_modified/docs/images/pi_zero_pieces.jpg
rename to essential/picamera_library_modified/docs/images/pi_zero_pieces.jpg
diff --git a/picamera_library_modified/docs/images/picamera_pipeline.dot b/essential/picamera_library_modified/docs/images/picamera_pipeline.dot
similarity index 100%
rename from picamera_library_modified/docs/images/picamera_pipeline.dot
rename to essential/picamera_library_modified/docs/images/picamera_pipeline.dot
diff --git a/picamera_library_modified/docs/images/picamera_pipeline.pdf b/essential/picamera_library_modified/docs/images/picamera_pipeline.pdf
similarity index 100%
rename from picamera_library_modified/docs/images/picamera_pipeline.pdf
rename to essential/picamera_library_modified/docs/images/picamera_pipeline.pdf
diff --git a/picamera_library_modified/docs/images/picamera_pipeline.png b/essential/picamera_library_modified/docs/images/picamera_pipeline.png
similarity index 100%
rename from picamera_library_modified/docs/images/picamera_pipeline.png
rename to essential/picamera_library_modified/docs/images/picamera_pipeline.png
diff --git a/picamera_library_modified/docs/images/picamera_pipeline.svg b/essential/picamera_library_modified/docs/images/picamera_pipeline.svg
similarity index 100%
rename from picamera_library_modified/docs/images/picamera_pipeline.svg
rename to essential/picamera_library_modified/docs/images/picamera_pipeline.svg
diff --git a/picamera_library_modified/docs/images/preview_pipeline.dot b/essential/picamera_library_modified/docs/images/preview_pipeline.dot
similarity index 100%
rename from picamera_library_modified/docs/images/preview_pipeline.dot
rename to essential/picamera_library_modified/docs/images/preview_pipeline.dot
diff --git a/picamera_library_modified/docs/images/preview_pipeline.pdf b/essential/picamera_library_modified/docs/images/preview_pipeline.pdf
similarity index 100%
rename from picamera_library_modified/docs/images/preview_pipeline.pdf
rename to essential/picamera_library_modified/docs/images/preview_pipeline.pdf
diff --git a/picamera_library_modified/docs/images/preview_pipeline.png b/essential/picamera_library_modified/docs/images/preview_pipeline.png
similarity index 100%
rename from picamera_library_modified/docs/images/preview_pipeline.png
rename to essential/picamera_library_modified/docs/images/preview_pipeline.png
diff --git a/picamera_library_modified/docs/images/preview_pipeline.svg b/essential/picamera_library_modified/docs/images/preview_pipeline.svg
similarity index 100%
rename from picamera_library_modified/docs/images/preview_pipeline.svg
rename to essential/picamera_library_modified/docs/images/preview_pipeline.svg
diff --git a/picamera_library_modified/docs/images/rgb_capture_pipeline.dot b/essential/picamera_library_modified/docs/images/rgb_capture_pipeline.dot
similarity index 100%
rename from picamera_library_modified/docs/images/rgb_capture_pipeline.dot
rename to essential/picamera_library_modified/docs/images/rgb_capture_pipeline.dot
diff --git a/picamera_library_modified/docs/images/rgb_capture_pipeline.pdf b/essential/picamera_library_modified/docs/images/rgb_capture_pipeline.pdf
similarity index 100%
rename from picamera_library_modified/docs/images/rgb_capture_pipeline.pdf
rename to essential/picamera_library_modified/docs/images/rgb_capture_pipeline.pdf
diff --git a/picamera_library_modified/docs/images/rgb_capture_pipeline.png b/essential/picamera_library_modified/docs/images/rgb_capture_pipeline.png
similarity index 100%
rename from picamera_library_modified/docs/images/rgb_capture_pipeline.png
rename to essential/picamera_library_modified/docs/images/rgb_capture_pipeline.png
diff --git a/picamera_library_modified/docs/images/rgb_capture_pipeline.svg b/essential/picamera_library_modified/docs/images/rgb_capture_pipeline.svg
similarity index 100%
rename from picamera_library_modified/docs/images/rgb_capture_pipeline.svg
rename to essential/picamera_library_modified/docs/images/rgb_capture_pipeline.svg
diff --git a/picamera_library_modified/docs/images/sensor_area_1.png b/essential/picamera_library_modified/docs/images/sensor_area_1.png
similarity index 100%
rename from picamera_library_modified/docs/images/sensor_area_1.png
rename to essential/picamera_library_modified/docs/images/sensor_area_1.png
diff --git a/picamera_library_modified/docs/images/sensor_area_1.xcf b/essential/picamera_library_modified/docs/images/sensor_area_1.xcf
similarity index 100%
rename from picamera_library_modified/docs/images/sensor_area_1.xcf
rename to essential/picamera_library_modified/docs/images/sensor_area_1.xcf
diff --git a/picamera_library_modified/docs/images/sensor_area_2.png b/essential/picamera_library_modified/docs/images/sensor_area_2.png
similarity index 100%
rename from picamera_library_modified/docs/images/sensor_area_2.png
rename to essential/picamera_library_modified/docs/images/sensor_area_2.png
diff --git a/picamera_library_modified/docs/images/sensor_area_2.xcf b/essential/picamera_library_modified/docs/images/sensor_area_2.xcf
similarity index 100%
rename from picamera_library_modified/docs/images/sensor_area_2.xcf
rename to essential/picamera_library_modified/docs/images/sensor_area_2.xcf
diff --git a/picamera_library_modified/docs/images/still_port_capture.pdf b/essential/picamera_library_modified/docs/images/still_port_capture.pdf
similarity index 100%
rename from picamera_library_modified/docs/images/still_port_capture.pdf
rename to essential/picamera_library_modified/docs/images/still_port_capture.pdf
diff --git a/picamera_library_modified/docs/images/still_port_capture.png b/essential/picamera_library_modified/docs/images/still_port_capture.png
similarity index 100%
rename from picamera_library_modified/docs/images/still_port_capture.png
rename to essential/picamera_library_modified/docs/images/still_port_capture.png
diff --git a/picamera_library_modified/docs/images/still_port_capture.svg b/essential/picamera_library_modified/docs/images/still_port_capture.svg
similarity index 100%
rename from picamera_library_modified/docs/images/still_port_capture.svg
rename to essential/picamera_library_modified/docs/images/still_port_capture.svg
diff --git a/picamera_library_modified/docs/images/still_raw_capture.pdf b/essential/picamera_library_modified/docs/images/still_raw_capture.pdf
similarity index 100%
rename from picamera_library_modified/docs/images/still_raw_capture.pdf
rename to essential/picamera_library_modified/docs/images/still_raw_capture.pdf
diff --git a/picamera_library_modified/docs/images/still_raw_capture.png b/essential/picamera_library_modified/docs/images/still_raw_capture.png
similarity index 100%
rename from picamera_library_modified/docs/images/still_raw_capture.png
rename to essential/picamera_library_modified/docs/images/still_raw_capture.png
diff --git a/picamera_library_modified/docs/images/still_raw_capture.svg b/essential/picamera_library_modified/docs/images/still_raw_capture.svg
similarity index 100%
rename from picamera_library_modified/docs/images/still_raw_capture.svg
rename to essential/picamera_library_modified/docs/images/still_raw_capture.svg
diff --git a/picamera_library_modified/docs/images/versions.pdf b/essential/picamera_library_modified/docs/images/versions.pdf
similarity index 100%
rename from picamera_library_modified/docs/images/versions.pdf
rename to essential/picamera_library_modified/docs/images/versions.pdf
diff --git a/picamera_library_modified/docs/images/versions.png b/essential/picamera_library_modified/docs/images/versions.png
similarity index 100%
rename from picamera_library_modified/docs/images/versions.png
rename to essential/picamera_library_modified/docs/images/versions.png
diff --git a/picamera_library_modified/docs/images/versions.svg b/essential/picamera_library_modified/docs/images/versions.svg
similarity index 100%
rename from picamera_library_modified/docs/images/versions.svg
rename to essential/picamera_library_modified/docs/images/versions.svg
diff --git a/picamera_library_modified/docs/images/video_fullfov_record.pdf b/essential/picamera_library_modified/docs/images/video_fullfov_record.pdf
similarity index 100%
rename from picamera_library_modified/docs/images/video_fullfov_record.pdf
rename to essential/picamera_library_modified/docs/images/video_fullfov_record.pdf
diff --git a/picamera_library_modified/docs/images/video_fullfov_record.png b/essential/picamera_library_modified/docs/images/video_fullfov_record.png
similarity index 100%
rename from picamera_library_modified/docs/images/video_fullfov_record.png
rename to essential/picamera_library_modified/docs/images/video_fullfov_record.png
diff --git a/picamera_library_modified/docs/images/video_fullfov_record.svg b/essential/picamera_library_modified/docs/images/video_fullfov_record.svg
similarity index 100%
rename from picamera_library_modified/docs/images/video_fullfov_record.svg
rename to essential/picamera_library_modified/docs/images/video_fullfov_record.svg
diff --git a/picamera_library_modified/docs/images/video_port_capture.pdf b/essential/picamera_library_modified/docs/images/video_port_capture.pdf
similarity index 100%
rename from picamera_library_modified/docs/images/video_port_capture.pdf
rename to essential/picamera_library_modified/docs/images/video_port_capture.pdf
diff --git a/picamera_library_modified/docs/images/video_port_capture.png b/essential/picamera_library_modified/docs/images/video_port_capture.png
similarity index 100%
rename from picamera_library_modified/docs/images/video_port_capture.png
rename to essential/picamera_library_modified/docs/images/video_port_capture.png
diff --git a/picamera_library_modified/docs/images/video_port_capture.svg b/essential/picamera_library_modified/docs/images/video_port_capture.svg
similarity index 100%
rename from picamera_library_modified/docs/images/video_port_capture.svg
rename to essential/picamera_library_modified/docs/images/video_port_capture.svg
diff --git a/picamera_library_modified/docs/images/video_port_record.pdf b/essential/picamera_library_modified/docs/images/video_port_record.pdf
similarity index 100%
rename from picamera_library_modified/docs/images/video_port_record.pdf
rename to essential/picamera_library_modified/docs/images/video_port_record.pdf
diff --git a/picamera_library_modified/docs/images/video_port_record.png b/essential/picamera_library_modified/docs/images/video_port_record.png
similarity index 100%
rename from picamera_library_modified/docs/images/video_port_record.png
rename to essential/picamera_library_modified/docs/images/video_port_record.png
diff --git a/picamera_library_modified/docs/images/video_port_record.svg b/essential/picamera_library_modified/docs/images/video_port_record.svg
similarity index 100%
rename from picamera_library_modified/docs/images/video_port_record.svg
rename to essential/picamera_library_modified/docs/images/video_port_record.svg
diff --git a/picamera_library_modified/docs/images/yuv420.pdf b/essential/picamera_library_modified/docs/images/yuv420.pdf
similarity index 100%
rename from picamera_library_modified/docs/images/yuv420.pdf
rename to essential/picamera_library_modified/docs/images/yuv420.pdf
diff --git a/picamera_library_modified/docs/images/yuv420.png b/essential/picamera_library_modified/docs/images/yuv420.png
similarity index 100%
rename from picamera_library_modified/docs/images/yuv420.png
rename to essential/picamera_library_modified/docs/images/yuv420.png
diff --git a/picamera_library_modified/docs/images/yuv420.svg b/essential/picamera_library_modified/docs/images/yuv420.svg
similarity index 100%
rename from picamera_library_modified/docs/images/yuv420.svg
rename to essential/picamera_library_modified/docs/images/yuv420.svg
diff --git a/picamera_library_modified/docs/index.rst b/essential/picamera_library_modified/docs/index.rst
similarity index 100%
rename from picamera_library_modified/docs/index.rst
rename to essential/picamera_library_modified/docs/index.rst
diff --git a/picamera_library_modified/docs/install.rst b/essential/picamera_library_modified/docs/install.rst
similarity index 100%
rename from picamera_library_modified/docs/install.rst
rename to essential/picamera_library_modified/docs/install.rst
diff --git a/picamera_library_modified/docs/license.rst b/essential/picamera_library_modified/docs/license.rst
similarity index 100%
rename from picamera_library_modified/docs/license.rst
rename to essential/picamera_library_modified/docs/license.rst
diff --git a/picamera_library_modified/docs/quickstart.rst b/essential/picamera_library_modified/docs/quickstart.rst
similarity index 100%
rename from picamera_library_modified/docs/quickstart.rst
rename to essential/picamera_library_modified/docs/quickstart.rst
diff --git a/picamera_library_modified/docs/recipes1.rst b/essential/picamera_library_modified/docs/recipes1.rst
similarity index 100%
rename from picamera_library_modified/docs/recipes1.rst
rename to essential/picamera_library_modified/docs/recipes1.rst
diff --git a/picamera_library_modified/docs/recipes2.rst b/essential/picamera_library_modified/docs/recipes2.rst
similarity index 100%
rename from picamera_library_modified/docs/recipes2.rst
rename to essential/picamera_library_modified/docs/recipes2.rst
diff --git a/picamera_library_modified/picamera.egg-info/PKG-INFO b/essential/picamera_library_modified/picamera.egg-info/PKG-INFO
similarity index 100%
rename from picamera_library_modified/picamera.egg-info/PKG-INFO
rename to essential/picamera_library_modified/picamera.egg-info/PKG-INFO
diff --git a/picamera_library_modified/picamera.egg-info/SOURCES.txt b/essential/picamera_library_modified/picamera.egg-info/SOURCES.txt
similarity index 100%
rename from picamera_library_modified/picamera.egg-info/SOURCES.txt
rename to essential/picamera_library_modified/picamera.egg-info/SOURCES.txt
diff --git a/essential/picamera_library_modified/picamera.egg-info/dependency_links.txt b/essential/picamera_library_modified/picamera.egg-info/dependency_links.txt
new file mode 100755
index 0000000..8b13789
--- /dev/null
+++ b/essential/picamera_library_modified/picamera.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/picamera_library_modified/picamera.egg-info/requires.txt b/essential/picamera_library_modified/picamera.egg-info/requires.txt
similarity index 100%
rename from picamera_library_modified/picamera.egg-info/requires.txt
rename to essential/picamera_library_modified/picamera.egg-info/requires.txt
diff --git a/picamera_library_modified/picamera.egg-info/top_level.txt b/essential/picamera_library_modified/picamera.egg-info/top_level.txt
similarity index 100%
rename from picamera_library_modified/picamera.egg-info/top_level.txt
rename to essential/picamera_library_modified/picamera.egg-info/top_level.txt
diff --git a/picamera_library_modified/picamera/__init__.py b/essential/picamera_library_modified/picamera/__init__.py
similarity index 100%
rename from picamera_library_modified/picamera/__init__.py
rename to essential/picamera_library_modified/picamera/__init__.py
diff --git a/picamera_library_modified/picamera/array.py b/essential/picamera_library_modified/picamera/array.py
similarity index 100%
rename from picamera_library_modified/picamera/array.py
rename to essential/picamera_library_modified/picamera/array.py
diff --git a/picamera_library_modified/picamera/bcm_host.py b/essential/picamera_library_modified/picamera/bcm_host.py
similarity index 100%
rename from picamera_library_modified/picamera/bcm_host.py
rename to essential/picamera_library_modified/picamera/bcm_host.py
diff --git a/picamera_library_modified/picamera/camera.py b/essential/picamera_library_modified/picamera/camera.py
similarity index 100%
rename from picamera_library_modified/picamera/camera.py
rename to essential/picamera_library_modified/picamera/camera.py
diff --git a/picamera_library_modified/picamera/color.py b/essential/picamera_library_modified/picamera/color.py
similarity index 100%
rename from picamera_library_modified/picamera/color.py
rename to essential/picamera_library_modified/picamera/color.py
diff --git a/picamera_library_modified/picamera/display.py b/essential/picamera_library_modified/picamera/display.py
similarity index 100%
rename from picamera_library_modified/picamera/display.py
rename to essential/picamera_library_modified/picamera/display.py
diff --git a/picamera_library_modified/picamera/encoders.py b/essential/picamera_library_modified/picamera/encoders.py
similarity index 100%
rename from picamera_library_modified/picamera/encoders.py
rename to essential/picamera_library_modified/picamera/encoders.py
diff --git a/picamera_library_modified/picamera/exc.py b/essential/picamera_library_modified/picamera/exc.py
similarity index 100%
rename from picamera_library_modified/picamera/exc.py
rename to essential/picamera_library_modified/picamera/exc.py
diff --git a/picamera_library_modified/picamera/frames.py b/essential/picamera_library_modified/picamera/frames.py
similarity index 100%
rename from picamera_library_modified/picamera/frames.py
rename to essential/picamera_library_modified/picamera/frames.py
diff --git a/picamera_library_modified/picamera/mmal.py b/essential/picamera_library_modified/picamera/mmal.py
similarity index 100%
rename from picamera_library_modified/picamera/mmal.py
rename to essential/picamera_library_modified/picamera/mmal.py
diff --git a/picamera_library_modified/picamera/mmalobj.py b/essential/picamera_library_modified/picamera/mmalobj.py
similarity index 100%
rename from picamera_library_modified/picamera/mmalobj.py
rename to essential/picamera_library_modified/picamera/mmalobj.py
diff --git a/picamera_library_modified/picamera/renderers.py b/essential/picamera_library_modified/picamera/renderers.py
similarity index 100%
rename from picamera_library_modified/picamera/renderers.py
rename to essential/picamera_library_modified/picamera/renderers.py
diff --git a/picamera_library_modified/picamera/streams.py b/essential/picamera_library_modified/picamera/streams.py
similarity index 100%
rename from picamera_library_modified/picamera/streams.py
rename to essential/picamera_library_modified/picamera/streams.py
diff --git a/picamera_library_modified/py32dev_requirements.txt b/essential/picamera_library_modified/py32dev_requirements.txt
similarity index 100%
rename from picamera_library_modified/py32dev_requirements.txt
rename to essential/picamera_library_modified/py32dev_requirements.txt
diff --git a/picamera_library_modified/rtd_requirements.txt b/essential/picamera_library_modified/rtd_requirements.txt
similarity index 100%
rename from picamera_library_modified/rtd_requirements.txt
rename to essential/picamera_library_modified/rtd_requirements.txt
diff --git a/picamera_library_modified/setup.py b/essential/picamera_library_modified/setup.py
similarity index 100%
rename from picamera_library_modified/setup.py
rename to essential/picamera_library_modified/setup.py
diff --git a/picamera_library_modified/tests/conftest.py b/essential/picamera_library_modified/tests/conftest.py
similarity index 100%
rename from picamera_library_modified/tests/conftest.py
rename to essential/picamera_library_modified/tests/conftest.py
diff --git a/picamera_library_modified/tests/test_array.py b/essential/picamera_library_modified/tests/test_array.py
similarity index 100%
rename from picamera_library_modified/tests/test_array.py
rename to essential/picamera_library_modified/tests/test_array.py
diff --git a/picamera_library_modified/tests/test_attr.py b/essential/picamera_library_modified/tests/test_attr.py
similarity index 100%
rename from picamera_library_modified/tests/test_attr.py
rename to essential/picamera_library_modified/tests/test_attr.py
diff --git a/picamera_library_modified/tests/test_capture.py b/essential/picamera_library_modified/tests/test_capture.py
similarity index 100%
rename from picamera_library_modified/tests/test_capture.py
rename to essential/picamera_library_modified/tests/test_capture.py
diff --git a/picamera_library_modified/tests/test_exc.py b/essential/picamera_library_modified/tests/test_exc.py
similarity index 100%
rename from picamera_library_modified/tests/test_exc.py
rename to essential/picamera_library_modified/tests/test_exc.py
diff --git a/picamera_library_modified/tests/test_misc.py b/essential/picamera_library_modified/tests/test_misc.py
similarity index 100%
rename from picamera_library_modified/tests/test_misc.py
rename to essential/picamera_library_modified/tests/test_misc.py
diff --git a/picamera_library_modified/tests/test_record.py b/essential/picamera_library_modified/tests/test_record.py
similarity index 100%
rename from picamera_library_modified/tests/test_record.py
rename to essential/picamera_library_modified/tests/test_record.py
diff --git a/picamera_library_modified/tests/test_streams.py b/essential/picamera_library_modified/tests/test_streams.py
similarity index 100%
rename from picamera_library_modified/tests/test_streams.py
rename to essential/picamera_library_modified/tests/test_streams.py
diff --git a/picamera_library_modified/tests/verify.py b/essential/picamera_library_modified/tests/verify.py
similarity index 100%
rename from picamera_library_modified/tests/verify.py
rename to essential/picamera_library_modified/tests/verify.py
diff --git a/pygame_matplotlib/__init__.py b/essential/pygame_matplotlib/__init__.py
similarity index 100%
rename from pygame_matplotlib/__init__.py
rename to essential/pygame_matplotlib/__init__.py
diff --git a/pygame_matplotlib/backend_pygame.py b/essential/pygame_matplotlib/backend_pygame.py
similarity index 100%
rename from pygame_matplotlib/backend_pygame.py
rename to essential/pygame_matplotlib/backend_pygame.py
diff --git a/pygame_matplotlib/gui_window.py b/essential/pygame_matplotlib/gui_window.py
similarity index 100%
rename from pygame_matplotlib/gui_window.py
rename to essential/pygame_matplotlib/gui_window.py
diff --git a/essential/scripts/__init__.py b/essential/scripts/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/essential/scripts/__init__.py
@@ -0,0 +1 @@
+
diff --git a/scripts/root_crontab.sh b/essential/scripts/root_crontab.sh
similarity index 100%
rename from scripts/root_crontab.sh
rename to essential/scripts/root_crontab.sh
diff --git a/scripts/user_crontab.sh b/essential/scripts/user_crontab.sh
similarity index 100%
rename from scripts/user_crontab.sh
rename to essential/scripts/user_crontab.sh
diff --git a/essential/sound/001-beep.wav b/essential/sound/001-beep.wav
new file mode 100644
index 0000000..4959964
Binary files /dev/null and b/essential/sound/001-beep.wav differ
diff --git a/essential/sound/002-buzz.wav b/essential/sound/002-buzz.wav
new file mode 100644
index 0000000..428916f
Binary files /dev/null and b/essential/sound/002-buzz.wav differ
diff --git a/essential/sound/003-buzz.wav b/essential/sound/003-buzz.wav
new file mode 100644
index 0000000..428916f
Binary files /dev/null and b/essential/sound/003-buzz.wav differ
diff --git a/essential/sound/004-white-noise-44-1-16bit.wav b/essential/sound/004-white-noise-44-1-16bit.wav
new file mode 100644
index 0000000..f0d50a8
Binary files /dev/null and b/essential/sound/004-white-noise-44-1-16bit.wav differ
diff --git a/syringe_pump_c_code/main.c b/essential/syringe_pump_c_code/main.c
similarity index 100%
rename from syringe_pump_c_code/main.c
rename to essential/syringe_pump_c_code/main.c
diff --git a/syringe_pump_c_code/main.py b/essential/syringe_pump_c_code/main.py
similarity index 100%
rename from syringe_pump_c_code/main.py
rename to essential/syringe_pump_c_code/main.py
diff --git a/syringe_pump_c_code/main.so b/essential/syringe_pump_c_code/main.so
similarity index 100%
rename from syringe_pump_c_code/main.so
rename to essential/syringe_pump_c_code/main.so
diff --git a/syringe_pump_c_code/readme.md b/essential/syringe_pump_c_code/readme.md
similarity index 100%
rename from syringe_pump_c_code/readme.md
rename to essential/syringe_pump_c_code/readme.md
diff --git a/treadmill/Bounce2-master (1).zip b/essential/treadmill/Bounce2-master (1).zip
similarity index 100%
rename from treadmill/Bounce2-master (1).zip
rename to essential/treadmill/Bounce2-master (1).zip
diff --git a/treadmill/Treadmill.ino b/essential/treadmill/Treadmill.ino
similarity index 100%
rename from treadmill/Treadmill.ino
rename to essential/treadmill/Treadmill.ino
diff --git a/treadmill/Treadmill_20200302.ino b/essential/treadmill/Treadmill_20200302.ino
similarity index 100%
rename from treadmill/Treadmill_20200302.ino
rename to essential/treadmill/Treadmill_20200302.ino
diff --git a/treadmill/Treadmill_20211112.ino b/essential/treadmill/Treadmill_20211112.ino
similarity index 100%
rename from treadmill/Treadmill_20211112.ino
rename to essential/treadmill/Treadmill_20211112.ino
diff --git a/essential/treadmill/__init__.py b/essential/treadmill/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/essential/treadmill/__init__.py
@@ -0,0 +1 @@
+
diff --git a/treadmill/digitalWriteFast-master (1).zip b/essential/treadmill/digitalWriteFast-master (1).zip
similarity index 100%
rename from treadmill/digitalWriteFast-master (1).zip
rename to essential/treadmill/digitalWriteFast-master (1).zip
diff --git a/treadmill/readme.md b/essential/treadmill/readme.md
similarity index 100%
rename from treadmill/readme.md
rename to essential/treadmill/readme.md
diff --git a/treadmill/treadmill_current.ino b/essential/treadmill/treadmill_current.ino
similarity index 100%
rename from treadmill/treadmill_current.ino
rename to essential/treadmill/treadmill_current.ino
diff --git a/treadmill_distance.ino b/essential/treadmill/treadmill_distance.ino
similarity index 100%
rename from treadmill_distance.ino
rename to essential/treadmill/treadmill_distance.ino
diff --git a/treadmill_i2c.py b/essential/treadmill/treadmill_i2c.py
similarity index 100%
rename from treadmill_i2c.py
rename to essential/treadmill/treadmill_i2c.py
diff --git a/video_acquisition/README.md b/essential/video_acquisition/README.md
similarity index 100%
rename from video_acquisition/README.md
rename to essential/video_acquisition/README.md
diff --git a/video_acquisition/StartAcquisition_gpio.py b/essential/video_acquisition/StartAcquisition_gpio.py
similarity index 100%
rename from video_acquisition/StartAcquisition_gpio.py
rename to essential/video_acquisition/StartAcquisition_gpio.py
diff --git a/video_acquisition/VideoCapture.py b/essential/video_acquisition/VideoCapture.py
similarity index 100%
rename from video_acquisition/VideoCapture.py
rename to essential/video_acquisition/VideoCapture.py
diff --git a/essential/video_acquisition/__init__.py b/essential/video_acquisition/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/essential/video_acquisition/__init__.py
@@ -0,0 +1 @@
+
diff --git a/video_acquisition/control_acquisition.py b/essential/video_acquisition/control_acquisition.py
similarity index 100%
rename from video_acquisition/control_acquisition.py
rename to essential/video_acquisition/control_acquisition.py
diff --git a/video_acquisition/killrecording.py b/essential/video_acquisition/killrecording.py
similarity index 100%
rename from video_acquisition/killrecording.py
rename to essential/video_acquisition/killrecording.py
diff --git a/video_acquisition/start_acquisition.py b/essential/video_acquisition/start_acquisition.py
similarity index 100%
rename from video_acquisition/start_acquisition.py
rename to essential/video_acquisition/start_acquisition.py
diff --git a/video_acquisition/start_acquisition_old.py b/essential/video_acquisition/start_acquisition_old.py
similarity index 100%
rename from video_acquisition/start_acquisition_old.py
rename to essential/video_acquisition/start_acquisition_old.py
diff --git a/start_preview.py b/essential/video_acquisition/start_preview.py
similarity index 100%
rename from start_preview.py
rename to essential/video_acquisition/start_preview.py
diff --git a/video_acquisition/stop_acquisition.sh b/essential/video_acquisition/stop_acquisition.sh
similarity index 100%
rename from video_acquisition/stop_acquisition.sh
rename to essential/video_acquisition/stop_acquisition.sh
diff --git a/stop_preview.sh b/essential/video_acquisition/stop_preview.sh
similarity index 100%
rename from stop_preview.sh
rename to essential/video_acquisition/stop_preview.sh
diff --git a/stop_video b/essential/video_acquisition/stop_video
similarity index 100%
rename from stop_video
rename to essential/video_acquisition/stop_video
diff --git a/essential/visual_stimuli/__init__.py b/essential/visual_stimuli/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/essential/visual_stimuli/__init__.py
@@ -0,0 +1 @@
+
diff --git a/visual_stimuli/readme.md b/essential/visual_stimuli/readme.md
similarity index 100%
rename from visual_stimuli/readme.md
rename to essential/visual_stimuli/readme.md
diff --git a/visual_stimuli/vstest.py b/essential/visual_stimuli/vstest.py
similarity index 100%
rename from visual_stimuli/vstest.py
rename to essential/visual_stimuli/vstest.py
diff --git a/visualstim.py b/essential/visualstim.py
similarity index 100%
rename from visualstim.py
rename to essential/visualstim.py
diff --git a/behavbox_v2.py b/obsolete/behavbox_v2.py
similarity index 100%
rename from behavbox_v2.py
rename to obsolete/behavbox_v2.py
diff --git a/fake_session_info.py b/obsolete/fake_session_info.py
similarity index 100%
rename from fake_session_info.py
rename to obsolete/fake_session_info.py
diff --git a/headfixed2FC_task.py b/obsolete/headfixed2FC_task_old.py
similarity index 93%
rename from headfixed2FC_task.py
rename to obsolete/headfixed2FC_task_old.py
index 9b28b8a..996b29b 100644
--- a/headfixed2FC_task.py
+++ b/obsolete/headfixed2FC_task_old.py
@@ -123,8 +123,8 @@ def __init__(self, **kwargs): # name and session_info should be provided as kwa
self.wrong_choice_error = False
self.multiple_choice_error = False
self.error_repeat = False
- self.reward_time_start = None # for reward_available state time keeping purpose
- self.reward_time = 10 # sec. could be incorporate into the session_info; available time for reward
+ self.reward_time_start = None # for reward_available state time keeping purpose
+ self.reward_time = 10 # sec. could be incorporate into the session_info; available time for reward
self.reward_times_up = False
self.block_count = 0
@@ -160,6 +160,7 @@ def __init__(self, **kwargs): # name and session_info should be provided as kwa
# session_statistics
self.total_reward = 0
self.correct_trial_in_block = 0
+
########################################################################
# functions called when state transitions occur
########################################################################
@@ -205,7 +206,6 @@ def run(self):
self.restart()
# first detect the lick signal:
cue_state = self.current_card[0]
- # side_choice = self.current_card[2]
side_mice = None
if self.event_name == "left_entry":
side_mice = 'left'
@@ -222,34 +222,35 @@ def run(self):
if cue_state == 'all':
side_choice = side_mice
if side_choice == 'left':
- reward_size = self.current_card[2][0]
+ left_reward = self.session_info['reward_size'][self.current_card[2][0]]
+ reward_size = random.uniform(left_reward - self.session_info['reward_deviation'],
+ left_reward + self.session_info['reward_deviation'])
pump_num = self.current_card[3][0]
elif side_choice == 'right':
- reward_size = self.current_card[2][1]
+ right_reward = self.session_info['reward_size'][self.current_card[2][1]]
+ reward_size = random.uniform(right_reward - self.session_info['reward_deviation'],
+ right_reward + self.session_info['reward_deviation'])
pump_num = self.current_card[3][1]
else:
side_choice = self.current_card[1]
- reward_size = self.current_card[2]
+ forced_reward = self.session_info['reward_size'][self.current_card[2]]
+ reward_size = random.uniform(forced_reward - self.session_info['reward_deviation'],
+ forced_reward + self.session_info['reward_deviation'])
pump_num = self.current_card[3]
if side_mice == side_choice: # if the animal chose correctly
print("Number of lick detected: " + str(self.lick_count))
if self.lick_count == 0: # if this is the first lick
- # self.side_mice_buffer = side_mice
- self.pump.reward(pump_num, self.session_info["reward_size"][reward_size])
+ self.pump.reward(pump_num, reward_size)
self.total_reward += 1
self.correct_trial_in_block += 1
self.reward_time_start = time.time()
print("Reward time start" + str(self.reward_time_start))
self.lick_count += 1
-
elif self.side_mice_buffer:
if self.lick_count == 0:
self.check_cue('sound2')
self.wrong_choice_error = True
self.restart()
- #else: # wrong side - wrong_choice error
- # self.multiple_choice_error = True
- # self.restart()
# look for keystrokes
self.box.check_keybd()
@@ -331,11 +332,6 @@ def exit_reward_available(self):
self.error_repeat = True
self.error_list.append('wrong_choice_error')
self.wrong_choice_error = False
- #elif self.multiple_choice_error:
- # logging.info(";" + str(time.time()) + ";[error];multiple_choice_error;" + str(self.error_repeat))
- # self.error_repeat = False
- # self.error_list.append('multiple_choice_error')
- # self.multiple_choice_error = False
elif self.lick_count == 0:
logging.info(";" + str(time.time()) + ";[error];no_choice_error;" + str(self.error_repeat))
self.error_repeat = True
@@ -360,16 +356,13 @@ def check_cue(self, cue):
# self.LED_blink = True
self.box.cueLED2.on()
logging.info(";" + str(time.time()) + ";[cue];cueLED_R_on;" + str(self.error_repeat))
- elif cue =='all':
- #self.box.cueLED1.blink(0.2, 0.1)
+ elif cue == 'all':
self.box.cueLED1.on()
self.box.cueLED2.on()
logging.info(";" + str(time.time()) + ";[cue];LED_L+R_on; " + str(self.error_repeat))
def cue_off(self, cue):
if cue == 'all':
- #self.box.sound1.off()
- #self.box.sound2.off()
self.box.cueLED1.off()
self.box.cueLED2.off()
elif cue == 'sound1':
@@ -380,7 +373,6 @@ def cue_off(self, cue):
logging.info(";" + str(time.time()) + ";[cue];cue_sound2_off;" + str(self.error_repeat))
elif cue == 'LED_L':
self.box.cueLED1.off()
- #self.LED_blink = False
logging.info(";" + str(time.time()) + ";[cue];cueLED1_off;" + str(self.error_repeat))
elif cue == 'LED_R':
self.box.cueLED2.off()
@@ -406,8 +398,6 @@ def update_plot_error(self):
ticks = range(len(counts))
fig, ax = plt.subplots(1, 1, )
ax.bar(ticks, counts, align='center', tick_label=labels)
- # plt.xticks(ticks, labels)
- # plt.title(session_name)
ax = plt.gca()
ax.set_xticks(ticks, labels)
ax.set_xticklabels(labels=labels, rotation=70)
diff --git a/headfixed_task.py b/obsolete/headfixed_task_old.py
similarity index 100%
rename from headfixed_task.py
rename to obsolete/headfixed_task_old.py
diff --git a/lick_task.py b/obsolete/lick_task.py
similarity index 100%
rename from lick_task.py
rename to obsolete/lick_task.py
diff --git a/pump_task.py b/obsolete/pump_task.py
similarity index 100%
rename from pump_task.py
rename to obsolete/pump_task.py
diff --git a/record_run_test.py b/obsolete/record_run_test.py
similarity index 100%
rename from record_run_test.py
rename to obsolete/record_run_test.py
diff --git a/run_flip_task.py b/obsolete/run_flip_task.py
similarity index 100%
rename from run_flip_task.py
rename to obsolete/run_flip_task.py
diff --git a/run_headfixed2FC_task.py b/obsolete/run_headfixed2FC_task.py
similarity index 100%
rename from run_headfixed2FC_task.py
rename to obsolete/run_headfixed2FC_task.py
diff --git a/run_headfixed_task.py b/obsolete/run_headfixed_task.py
similarity index 100%
rename from run_headfixed_task.py
rename to obsolete/run_headfixed_task.py
diff --git a/run_lick_task.py b/obsolete/run_lick_task.py
similarity index 100%
rename from run_lick_task.py
rename to obsolete/run_lick_task.py
diff --git a/run_season_task.py b/obsolete/run_season_task.py
similarity index 100%
rename from run_season_task.py
rename to obsolete/run_season_task.py
diff --git a/run_soyoun_task.py b/obsolete/run_soyoun_task.py
similarity index 100%
rename from run_soyoun_task.py
rename to obsolete/run_soyoun_task.py
diff --git a/run_visualization_task.py b/obsolete/run_visualization_task.py
similarity index 100%
rename from run_visualization_task.py
rename to obsolete/run_visualization_task.py
diff --git a/run_walk_task.py b/obsolete/run_walk_task.py
similarity index 100%
rename from run_walk_task.py
rename to obsolete/run_walk_task.py
diff --git a/session_info_headfixed.py b/obsolete/session_info_headfixed.py
similarity index 100%
rename from session_info_headfixed.py
rename to obsolete/session_info_headfixed.py
diff --git a/session_info_headfixed2FC.py b/obsolete/session_info_headfixed2FC.py
similarity index 85%
rename from session_info_headfixed2FC.py
rename to obsolete/session_info_headfixed2FC.py
index 54c165c..8136923 100644
--- a/session_info_headfixed2FC.py
+++ b/obsolete/session_info_headfixed2FC.py
@@ -55,6 +55,7 @@
session_info['choice'] = ['right', 'left'] # lick port
session_info['reward'] = ['small', 'large'] # reward size
session_info['reward_size'] = {'small': 5, 'large': 10}
+session_info['reward_deviation'] = 1
if session_info['phase'] == 1:
session_info['reward_size'] = {'small': 10, 'large': 10}
@@ -74,3 +75,14 @@
session_info['consecutive_control'] = False
if session_info['consecutive_control']:
session_info['consecutive_max'] = 3
+
+session_info["calibration_coefficient"] = {}
+
+session_info["calibration_coefficient"]['1'] = [0.13, 0] # highest power first
+session_info["calibration_coefficient"]['2'] = [0.13, 0]
+session_info["calibration_coefficient"]['3'] = [0.13, 0.0]
+session_info["calibration_coefficient"]['4'] = [0.13, 0.0]
+
+session_info['air_duration'] = 0
+session_info["vacuum_duration"] = 1
+session_info["key_reward_amount"] = 5
\ No newline at end of file
diff --git a/session_info_walk.py b/obsolete/session_info_walk.py
similarity index 100%
rename from session_info_walk.py
rename to obsolete/session_info_walk.py
diff --git a/soyoun_task.py b/obsolete/soyoun_task.py
similarity index 100%
rename from soyoun_task.py
rename to obsolete/soyoun_task.py
diff --git a/task_information_headfixed.py b/obsolete/task_information_headfixed.py
similarity index 100%
rename from task_information_headfixed.py
rename to obsolete/task_information_headfixed.py
diff --git a/task_information_headfixed2FC.py b/obsolete/task_information_headfixed2FC.py
similarity index 100%
rename from task_information_headfixed2FC.py
rename to obsolete/task_information_headfixed2FC.py
diff --git a/task_information_lick.py b/obsolete/task_information_lick.py
similarity index 100%
rename from task_information_lick.py
rename to obsolete/task_information_lick.py
diff --git a/task_information_phase_1.py b/obsolete/task_information_phase_1.py
similarity index 100%
rename from task_information_phase_1.py
rename to obsolete/task_information_phase_1.py
diff --git a/test_session_info.py b/obsolete/test_session_info.py
similarity index 100%
rename from test_session_info.py
rename to obsolete/test_session_info.py
diff --git a/testing_visualstim.py b/obsolete/testing_visualstim.py
similarity index 100%
rename from testing_visualstim.py
rename to obsolete/testing_visualstim.py
diff --git a/visualization_task.py b/obsolete/visualization_task.py
similarity index 100%
rename from visualization_task.py
rename to obsolete/visualization_task.py
diff --git a/walk_task.py b/obsolete/walk_task.py
similarity index 100%
rename from walk_task.py
rename to obsolete/walk_task.py
diff --git a/syringe_pump_pygame_debug.py b/syringe_pump_pygame_debug.py
deleted file mode 100644
index a2dfbcc..0000000
--- a/syringe_pump_pygame_debug.py
+++ /dev/null
@@ -1,38 +0,0 @@
-import pygame
-from behavbox import Pump
-import numpy as np
-try:
- pump = Pump()
- pygame.init()
- DISPLAYSURF = pygame.display.set_mode((200, 200))
- pygame.display.set_caption("pygame debugging")
-except Exception as error_message:
- print(str(error_message))
-
-run = True
-reward_size = float(input("Input reward_size: "))
-
-while run:
- for event in pygame.event.get():
- if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
- run = False
- if event.type == pygame.KEYDOWN:
- # print("KeyDown: " + str(event.type) + "\n")
- if event.key == pygame.K_q:
- print("Q down: syringe pump 1")
- pump.reward("1", reward_size)
- if event.key == pygame.K_w:
- print("W down: syringe pump 2")
- pump.reward("2", reward_size)
- if event.key == pygame.K_e:
- print("E down: syringe pump 3")
- pump.reward("3", reward_size)
- if event.key == pygame.K_r:
- print("R down: syringe pump 4")
- pump.reward("4", reward_size)
- if event.key == pygame.K_a:
- print("A down: air puff on")
- pump.reward("air_puff", reward_size)
- if event.key == pygame.K_s:
- print("S down: vacuum on")
- pump.reward("vacuum", 1)
\ No newline at end of file
diff --git a/EFO_task/EFO_task.py b/task_protocol/EFO_task/EFO_task.py
similarity index 98%
rename from EFO_task/EFO_task.py
rename to task_protocol/EFO_task/EFO_task.py
index 4eaddd7..5b86cde 100644
--- a/EFO_task/EFO_task.py
+++ b/task_protocol/EFO_task/EFO_task.py
@@ -26,7 +26,9 @@
}
)
# all modules above this line will have logging disabled
-
+# updated with reorganization (on 7/11/2023)
+import sys
+sys.path.insert(0,'/home/pi/RPi4_behavior_boxes/essential')
import behavbox
# adding timing capability to the state machine
diff --git a/task_protocol/EFO_task/__init__.py b/task_protocol/EFO_task/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/task_protocol/EFO_task/__init__.py
@@ -0,0 +1 @@
+
diff --git a/task_protocol/__init__.py b/task_protocol/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/task_protocol/__init__.py
@@ -0,0 +1 @@
+
diff --git a/task_protocol/headfixed_task/__init__.py b/task_protocol/headfixed_task/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/task_protocol/headfixed_task/__init__.py
@@ -0,0 +1 @@
+
diff --git a/task_protocol/headfixed_task/headfixed_independent_reward_task.py b/task_protocol/headfixed_task/headfixed_independent_reward_task.py
new file mode 100644
index 0000000..9484671
--- /dev/null
+++ b/task_protocol/headfixed_task/headfixed_independent_reward_task.py
@@ -0,0 +1,471 @@
+# python3: headfixed_task.py
+"""
+author: tian qiu & Soyoun Kim
+date: 2023-02-16
+name: headfixed2FC_task.py
+goal: model_free reinforcement learning behavioral training task structure
+description:
+ an updated test version of headfixed_task.py & add foraging reward condition
+
+"""
+import importlib
+from transitions import Machine
+from transitions import State
+from transitions.extensions.states import add_state_features, Timeout
+import pysistence, collections
+from icecream import ic
+import logging
+import time
+from datetime import datetime
+import os
+from gpiozero import PWMLED, LED, Button
+from colorama import Fore, Style
+import logging.config
+from time import sleep
+import random
+import threading
+import matplotlib
+import matplotlib.pyplot as plt
+import matplotlib.figure as fg
+import numpy as np
+
+logging.config.dictConfig(
+ {
+ "version": 1,
+ "disable_existing_loggers": True,
+ }
+)
+# all modules above this line will have logging disabled
+
+import sys
+sys.path.insert(0,'/home/pi/RPi4_behavior_boxes/essential')
+import behavbox
+
+
+# adding timing capability to the state machine
+@add_state_features(Timeout)
+class TimedStateMachine(Machine):
+ pass
+
+
+class HeadfixedIndependentRewardTask(object):
+ # Define states. States where the animals is waited to make their decision
+
+ def __init__(self, **kwargs): # name and session_info should be provided as kwargs
+
+ # if no name or session, make fake ones (for testing purposes)
+ if kwargs.get("name", None) is None:
+ self.name = "name"
+ print(
+ Fore.RED
+ + Style.BRIGHT
+ + "Warning: no name supplied; making fake one"
+ + Style.RESET_ALL
+ )
+ else:
+ self.name = kwargs.get("name", None)
+
+ if kwargs.get("session_info", None) is None:
+ print(
+ Fore.RED
+ + Style.BRIGHT
+ + "Warning: no session_info supplied; making fake one"
+ + Style.RESET_ALL
+ )
+ from fake_session_info import fake_session_info
+
+ self.session_info = fake_session_info
+ else:
+ self.session_info = kwargs.get("session_info", None)
+ ic(self.session_info)
+
+ # initialize the state machine
+ self.states = [
+ State(name='standby',
+ on_enter=["enter_standby"],
+ on_exit=["exit_standby"]),
+ Timeout(name="initiate",
+ on_enter=["enter_initiate"],
+ on_exit=["exit_initiate"],
+ timeout=self.session_info["initiation_timeout"],
+ on_timeout=["restart"]),
+ Timeout(name='cue_state',
+ on_enter=["enter_cue_state"],
+ on_exit=["exit_cue_state"],
+ timeout=self.session_info["cue_timeout"],
+ on_timeout=["restart"]),
+ Timeout(name='reward_available',
+ on_enter=["enter_reward_available"],
+ on_exit=["exit_reward_available"],
+ timeout=self.session_info["wait_for_choice"],
+ on_timeout=["restart"])
+ ]
+ self.transitions = [
+ ['start_trial', 'standby', 'initiate'],
+ ['start_cue', 'initiate', 'cue_state'],
+ ['evaluate_reward', 'cue_state', 'reward_available'],
+ ['restart', ['initiate', 'cue_state', 'reward_available'], 'standby']
+ ]
+
+ self.machine = TimedStateMachine(
+ model=self,
+ states=self.states,
+ transitions=self.transitions,
+ initial='standby'
+ )
+ self.trial_running = False
+
+ # trial statistics
+ self.correct_trial_number = 0
+ self.actual_trial_number = 0
+ self.error_count = 0
+ self.error_list = []
+ self.early_lick_error = False
+ self.initiate_error = False
+ self.cue_state_error = False
+ self.wrong_choice_error = True
+ self.multiple_choice_error = False
+ self.error_repeat = False
+
+ self.pump_num = None
+ self.reward_size = None
+ self.current_reward = None
+ self.reward_check = False
+ self.reward_size_offset = self.session_info['reward_size_offset']
+
+ self.block_count = 0
+ self.blocknumber = self.session_info["block_number"]
+ self.current_card = None
+ self.left_poke_count = 0
+ self.right_poke_count = 0
+ self.timeline_left_poke = []
+ self.left_poke_count_list = []
+ self.timeline_right_poke = []
+ self.right_poke_count_list = []
+ self.event_name = ""
+ # initialize behavior box
+ self.box = behavbox.BehavBox(self.session_info)
+ self.pump = self.box.pump
+
+ self.treadmill = self.box.treadmill
+
+ self.distance_initiation = self.session_info['treadmill_setup']['distance_initiation']
+ self.distance_cue = self.session_info['treadmill_setup']['distance_cue']
+ self.distance_buffer = None
+ self.distance_diff = 0
+
+ # for foragaing parameters
+ self.side_choice = None # whether free choice is left or right
+ self.cue_state = None
+
+ # for refining the lick detection
+ self.lick_count = 0
+ self.side_mice_buffer = None
+ self.LED_blink = False
+ try:
+ self.lick_threshold = self.session_info["lick_threshold"]
+ except:
+ print("No lick_threshold defined in session_info. Therefore, default defined as 2 \n")
+ self.lick_threshold = 1
+
+ # session_statistics
+ self.total_reward = 0
+
+ ########################################################################
+ # functions called when state transitions occur
+ ########################################################################
+ def run(self):
+ if self.box.event_list:
+ self.event_name = self.box.event_list.popleft()
+ else:
+ self.event_name = ""
+ # there can only be lick during the reward available state
+ # if lick detected prior to reward available state
+ # the trial will restart and transition to standby
+ if self.event_name is "left_entry" or self.event_name == "right_entry":
+ # print("EVENT NAME !!!!!! " + self.event_name)
+ if self.state == "reward_available" or self.state == "standby" or self.state == "initiate":
+ pass
+ else:
+ self.early_lick_error = True
+ self.error_repeat = True
+ self.restart()
+ if self.state == "standby":
+ pass
+ elif self.state == "initiate":
+ self.distance_diff = self.get_distance() - self.distance_buffer
+ if self.distance_diff >= self.distance_initiation:
+ self.initiate_error = False
+ self.start_cue()
+ else:
+ self.initiate_error = True
+ elif self.state == "cue_state":
+ self.distance_diff = self.get_distance() - self.distance_buffer
+ if self.distance_diff >= self.distance_cue:
+ self.cue_state_error = False
+ self.evaluate_reward()
+ else:
+ self.cue_state_error = True
+ elif self.state == "reward_available":
+ cue_state = self.current_card[0]
+ side_mice = None
+ if self.event_name == "left_entry":
+ side_mice = 'left'
+ self.left_poke_count += 1
+ self.left_poke_count_list.append(self.left_poke_count)
+ self.timeline_left_poke.append(time.time())
+ elif self.event_name == "right_entry":
+ side_mice = 'right'
+ self.right_poke_count += 1
+ self.right_poke_count_list.append(self.right_poke_count)
+ self.timeline_right_poke.append(time.time())
+ if side_mice:
+ self.side_mice_buffer = side_mice
+ self.cue_state = cue_state # cue state for foraging
+ if cue_state == 'all':
+ side_choice = side_mice
+ if side_choice == 'left':
+ self.pump_num = self.current_card[2][0]
+ self.reward_size = self.current_reward[0]
+ print("self.current_reward[0]: " + str(self.current_reward[0]))
+ elif side_choice == 'right':
+ self.pump_num = self.current_card[2][1]
+ self.reward_size = self.current_reward[1]
+ print("self.current_reward[0]: " + str(self.current_reward[1]))
+ elif cue_state == 'LED_L':
+ side_choice = self.current_card[1]
+ self.pump_num = self.current_card[2]
+ self.reward_size = self.current_reward[0]
+ elif cue_state == 'LED_R':
+ side_choice = self.current_card[1]
+ self.pump_num = self.current_card[2]
+ self.reward_size = self.current_reward[1]
+ print("!!!!!!!!CUE_STATE: " + str(cue_state))
+ if side_mice == side_choice: # if the animal chose correctly
+ self.side_mice_buffer = side_mice
+ if side_mice == side_choice: # if the animal chose correctly
+ if self.lick_count == 0: # if this is the first lick
+ self.side_choice = side_choice # foraging task
+ self.wrong_choice_error = False
+ self.reward_check = True
+ self.lick_count += 1
+ self.restart()
+ elif self.side_mice_buffer:
+ if self.lick_count == 0:
+ self.wrong_choice_error = True
+ self.lick_count += 1
+ self.restart()
+
+ # look for keystrokes
+ self.box.check_keybd()
+
+ def enter_standby(self):
+ logging.info(";" + str(time.time()) + ";[transition];enter_standby;" + str(self.error_repeat))
+ self.update_plot_choice()
+ # self.update_plot_error()
+ self.trial_running = False
+ # self.reward_error = False
+ if self.early_lick_error:
+ self.error_list.append("early_lick_error")
+ logging.info(";" + str(time.time()) + ";[error];early_lick_error;" + str(self.error_repeat))
+ self.check_cue('sound2')
+ self.early_lick_error = False
+ print(str(time.time()) + ", Total reward up till current session: " + str(self.total_reward))
+ logging.info(";" + str(time.time()) + ";[trial];trial_" + str(self.actual_trial_number) + ";" + str(self.error_repeat))
+
+ def exit_standby(self):
+ logging.info(";" + str(time.time()) + ";[transition];exit_standby;" + str(self.error_repeat))
+ self.lick_count = 0
+ self.side_mice_buffer = None
+ self.box.event_list.clear()
+ pass
+
+ def enter_initiate(self):
+ # print("!!!!!!!!!!!event name is " + self.event_name) # for debugging purposes
+ # check error_repeat
+ logging.info(";" + str(time.time()) + ";[transition];enter_initiate;" + str(self.error_repeat))
+ self.check_cue('sound1')
+ self.trial_running = True
+ # wait for treadmill signal and process the treadmill signal
+ self.distance_buffer = self.get_distance()
+ logging.info(
+ ";" + str(time.time()) + ";[treadmill];" + str(self.distance_buffer) + ";" + str(self.error_repeat))
+
+ def exit_initiate(self):
+ # check the flag to see whether to shuffle or keep the original card
+ logging.info(";" + str(time.time()) + ";[transition];exit_initiate;" + str(self.error_repeat))
+ print("EVENT NAME: " + str(self.box.event_list))
+ self.cue_off('sound1')
+ if self.initiate_error:
+ self.error_list.append('initiate_error')
+ self.error_repeat = True
+ logging.info(";" + str(time.time()) + ";[error];initiate_error;" + str(self.error_repeat))
+ self.error_count += 1
+
+ def enter_cue_state(self):
+ logging.info(";" + str(time.time()) + ";[transition];enter_cue_state;" + str(self.error_repeat))
+ # turn on the cue according to the current card
+ self.check_cue(self.current_card[0])
+ # wait for treadmill signal and process the treadmill signal
+ self.distance_buffer = self.get_distance()
+ logging.info(
+ ";" + str(time.time()) + ";[treadmill];" + str(self.distance_buffer) + ";" + str(self.error_repeat))
+
+ def exit_cue_state(self):
+ logging.info(";" + str(time.time()) + ";[transition];exit_cue_state;" + str(self.error_repeat))
+ self.cue_off(self.current_card[0])
+ if not self.early_lick_error:
+ if self.cue_state_error:
+ self.check_cue("sound2")
+ self.error_list.append('cue_state_error')
+ self.error_repeat = True
+ logging.info(";" + str(time.time()) + ";[error];cue_state_error;" + str(self.error_repeat))
+ self.error_count += 1
+ self.cue_state_error = False
+
+ def enter_reward_available(self):
+ logging.info(";" + str(time.time()) + ";[transition];enter_reward_available;" + str(self.error_repeat))
+ print(str(time.time()) + ", " + str(self.actual_trial_number) + ", cue_state distance satisfied")
+
+ def exit_reward_available(self):
+ logging.info(";" + str(time.time()) + ";[transition];exit_reward_available;" + str(self.error_repeat))
+ if self.lick_count == 0:
+ logging.info(";" + str(time.time()) + ";[error];no_choice_error;" + str(self.error_repeat))
+ self.check_cue('sound2')
+ self.error_repeat = True
+ self.error_count += 1
+ self.error_list.append('no_choice_error')
+ elif self.wrong_choice_error:
+ logging.info(";" + str(time.time()) + ";[error];wrong_choice_error;" + str(self.error_repeat))
+ self.check_cue('sound2')
+ self.error_repeat = True
+ self.error_count += 1
+ self.error_list.append('wrong_choice_error')
+ elif self.reward_check:
+ logging.info(";" + str(time.time()) + ";[error];correct_trial;" + str(self.error_repeat))
+ self.pump.reward(self.pump_num, self.reward_size)
+ self.error_repeat = False
+ self.total_reward += 1
+ self.reward_check = False
+ self.error_list.append('correct_trial')
+ self.pump_num = None
+ self.reward_size = None
+ self.wrong_choice_error = False
+
+
+ def check_cue(self, cue):
+ if cue == 'sound1':
+ logging.info(";" + str(time.time()) + ";[cue];cue_sound1_on;" + str(self.error_repeat))
+ self.box.sound1.on()
+ if cue == 'sound2':
+ logging.info(";" + str(time.time()) + ";[cue];cue_sound2_on;" + str(self.error_repeat))
+ self.box.sound2.blink(1, 0.1, 1)
+ elif cue == 'LED_L':
+ self.box.cueLED1.on()
+ logging.info(";" + str(time.time()) + ";[cue];cueLED_L_on;" + str(self.error_repeat))
+ elif cue == 'LED_R':
+ self.box.cueLED2.on()
+ logging.info(";" + str(time.time()) + ";[cue];cueLED_R_on;" + str(self.error_repeat))
+ elif cue == 'all':
+ self.box.cueLED1.on()
+ self.box.cueLED2.on()
+ logging.info(";" + str(time.time()) + ";[cue];LED_L+R_on; " + str(self.error_repeat))
+
+ def cue_off(self, cue):
+ if cue == 'all':
+ self.box.cueLED1.off()
+ self.box.cueLED2.off()
+ elif cue == 'sound1':
+ self.box.sound1.off()
+ logging.info(";" + str(time.time()) + ";[cue];cue_sound1_off;" + str(self.error_repeat))
+ elif cue == 'sound2':
+ self.box.sound2.off()
+ logging.info(";" + str(time.time()) + ";[cue];cue_sound2_off;" + str(self.error_repeat))
+ elif cue == 'LED_L':
+ self.box.cueLED1.off()
+ logging.info(";" + str(time.time()) + ";[cue];cueLED1_off;" + str(self.error_repeat))
+ elif cue == 'LED_R':
+ self.box.cueLED2.off()
+ logging.info(";" + str(time.time()) + ";[cue];cueLED2_off;" + str(self.error_repeat))
+
+ def get_distance(self):
+ try:
+ distance = self.treadmill.distance_cm
+ except Exception as e:
+ logging.info(";" + str(time.time()) + ";[system_error];" + str(e) + ";" + str(self.error_repeat))
+ self.treadmill = self.box.treadmill
+ distance = self.treadmill.distance_cm
+ return distance
+
+ def update_plot(self):
+ fig, axes = plt.subplots(1, 1, )
+ axes.plot([1, 2], [1, 2], color='green', label='test')
+ self.box.check_plot(fig)
+
+ def update_plot_error(self):
+ error_event = self.error_list
+ labels, counts = np.unique(error_event, return_counts=True)
+ ticks = range(len(counts))
+ fig, ax = plt.subplots(1, 1, )
+ ax.bar(ticks, counts, align='center', tick_label=labels)
+ ax = plt.gca()
+ ax.set_xticks(ticks, labels)
+ ax.set_xticklabels(labels=labels, rotation=70)
+
+ self.box.check_plot(fig)
+
+ def update_plot_choice(self, save_fig=False):
+ trajectory_left = self.left_poke_count_list
+ time_left = self.timeline_left_poke
+ trajectory_right = self.right_poke_count_list
+ time_right = self.timeline_right_poke
+ fig, ax = plt.subplots(1, 1, )
+ print(type(fig))
+
+ ax.plot(time_left, trajectory_left, color='b', marker="o", label='left_lick_trajectory')
+ ax.plot(time_right, trajectory_right, color='r', marker="o", label='right_lick_trajectory')
+ if save_fig:
+ plt.savefig(self.session_info['basedir'] + "/" + self.session_info['basename'] + "/" + \
+ self.session_info['basename'] + "_choice_plot" + '.png')
+ self.box.check_plot(fig)
+
+ def integrate_plot(self, save_fig=False):
+
+ fig, ax = plt.subplots(2, 1)
+
+ trajectory_left = self.left_poke_count_list
+ time_left = self.timeline_left_poke
+ trajectory_right = self.right_poke_count_list
+ time_right = self.timeline_right_poke
+ print(type(fig))
+
+ ax[0].plot(time_left, trajectory_left, color='b', marker="o", label='left_lick_trajectory')
+ ax[0].plot(time_right, trajectory_right, color='r', marker="o", label='right_lick_trajectory')
+
+ error_event = self.error_list
+ labels, counts = np.unique(error_event, return_counts=True)
+ ticks = range(len(counts))
+ ax[1].bar(ticks, counts, align='center', tick_label=labels)
+ # plt.xticks(ticks, labels)
+ # plt.title(session_name)
+ ax[1] = plt.gca()
+ ax[1].set_xticks(ticks, labels)
+ ax[1].set_xticklabels(labels=labels, rotation=70)
+
+ if save_fig:
+ plt.savefig(self.session_info['basedir'] + "/" + self.session_info['basename'] + "/" + \
+ self.session_info['basename'] + "_summery" + '.png')
+ self.box.check_plot(fig)
+
+ ########################################################################
+ # methods to start and end the behavioral session
+ ########################################################################
+
+ def start_session(self):
+ ic("TODO: start video")
+ self.box.video_start()
+
+ def end_session(self):
+ ic("TODO: stop video")
+ self.update_plot_choice(save_fig=True)
+ self.box.video_stop()
\ No newline at end of file
diff --git a/task_protocol/headfixed_task/headfixed_task.py b/task_protocol/headfixed_task/headfixed_task.py
new file mode 100644
index 0000000..76c6da0
--- /dev/null
+++ b/task_protocol/headfixed_task/headfixed_task.py
@@ -0,0 +1,470 @@
+# python3: headfixed_task.py
+"""
+author: tian qiu & Soyoun Kim
+date: 2023-02-16
+name: headfixed2FC_task.py
+goal: model_free reinforcement learning behavioral training task structure
+description:
+ an updated test version of headfixed_task.py & add foraging reward condition
+
+"""
+import importlib
+from transitions import Machine
+from transitions import State
+from transitions.extensions.states import add_state_features, Timeout
+import pysistence, collections
+from icecream import ic
+import logging
+import time
+from datetime import datetime
+import os
+from gpiozero import PWMLED, LED, Button
+from colorama import Fore, Style
+import logging.config
+from time import sleep
+import random
+import threading
+import matplotlib
+import matplotlib.pyplot as plt
+import matplotlib.figure as fg
+import numpy as np
+
+logging.config.dictConfig(
+ {
+ "version": 1,
+ "disable_existing_loggers": True,
+ }
+)
+# all modules above this line will have logging disabled
+import sys
+sys.path.insert(0,'/home/pi/RPi4_behavior_boxes/essential')
+import behavbox
+
+
+# adding timing capability to the state machine
+@add_state_features(Timeout)
+class TimedStateMachine(Machine):
+ pass
+
+
+class HeadfixedTask(object):
+ # Define states. States where the animals is waited to make their decision
+
+ def __init__(self, **kwargs): # name and session_info should be provided as kwargs
+
+ # if no name or session, make fake ones (for testing purposes)
+ if kwargs.get("name", None) is None:
+ self.name = "name"
+ print(
+ Fore.RED
+ + Style.BRIGHT
+ + "Warning: no name supplied; making fake one"
+ + Style.RESET_ALL
+ )
+ else:
+ self.name = kwargs.get("name", None)
+
+ if kwargs.get("session_info", None) is None:
+ print(
+ Fore.RED
+ + Style.BRIGHT
+ + "Warning: no session_info supplied; making fake one"
+ + Style.RESET_ALL
+ )
+ from fake_session_info import fake_session_info
+
+ self.session_info = fake_session_info
+ else:
+ self.session_info = kwargs.get("session_info", None)
+ ic(self.session_info)
+
+ # initialize the state machine
+ self.states = [
+ State(name='standby',
+ on_enter=["enter_standby"],
+ on_exit=["exit_standby"]),
+ Timeout(name="initiate",
+ on_enter=["enter_initiate"],
+ on_exit=["exit_initiate"],
+ timeout=self.session_info["initiation_timeout"],
+ on_timeout=["restart"]),
+ Timeout(name='cue_state',
+ on_enter=["enter_cue_state"],
+ on_exit=["exit_cue_state"],
+ timeout=self.session_info["cue_timeout"],
+ on_timeout=["restart"]),
+ Timeout(name='reward_available',
+ on_enter=["enter_reward_available"],
+ on_exit=["exit_reward_available"],
+ timeout=self.session_info["wait_for_choice"],
+ on_timeout=["restart"])
+ ]
+ self.transitions = [
+ ['start_trial', 'standby', 'initiate'],
+ ['start_cue', 'initiate', 'cue_state'],
+ ['evaluate_reward', 'cue_state', 'reward_available'],
+ ['restart', ['initiate', 'cue_state', 'reward_available'], 'standby']
+ ]
+
+ self.machine = TimedStateMachine(
+ model=self,
+ states=self.states,
+ transitions=self.transitions,
+ initial='standby'
+ )
+ self.trial_running = False
+
+ # trial statistics
+ self.correct_trial_number = 0
+ self.actual_trial_number = 0
+ self.error_count = 0
+ self.error_list = []
+ self.early_lick_error = False
+ self.initiate_error = False
+ self.cue_state_error = False
+ self.wrong_choice_error = True
+ self.multiple_choice_error = False
+ self.error_repeat = False
+
+ self.pump_num = None
+ self.reward_size = None
+ self.current_reward = None
+ self.reward_check = False
+ self.reward_size_offset = self.session_info['reward_size_offset']
+
+ self.block_count = 0
+ self.blocknumber = self.session_info["block_number"]
+ self.current_card = None
+ self.left_poke_count = 0
+ self.right_poke_count = 0
+ self.timeline_left_poke = []
+ self.left_poke_count_list = []
+ self.timeline_right_poke = []
+ self.right_poke_count_list = []
+ self.event_name = ""
+ # initialize behavior box
+ self.box = behavbox.BehavBox(self.session_info)
+ self.pump = self.box.pump
+
+ self.treadmill = self.box.treadmill
+
+ self.distance_initiation = self.session_info['treadmill_setup']['distance_initiation']
+ self.distance_cue = self.session_info['treadmill_setup']['distance_cue']
+ self.distance_buffer = None
+ self.distance_diff = 0
+
+ # for foragaing parameters
+ self.side_choice = None # whether free choice is left or right
+ self.cue_state = None
+
+ # for refining the lick detection
+ self.lick_count = 0
+ self.side_mice_buffer = None
+ self.LED_blink = False
+ try:
+ self.lick_threshold = self.session_info["lick_threshold"]
+ except:
+ print("No lick_threshold defined in session_info. Therefore, default defined as 2 \n")
+ self.lick_threshold = 1
+
+ # session_statistics
+ self.total_reward = 0
+
+ ########################################################################
+ # functions called when state transitions occur
+ ########################################################################
+ def run(self):
+ if self.box.event_list:
+ self.event_name = self.box.event_list.popleft()
+ else:
+ self.event_name = ""
+ # there can only be lick during the reward available state
+ # if lick detected prior to reward available state
+ # the trial will restart and transition to standby
+ if self.event_name is "left_entry" or self.event_name == "right_entry":
+ # print("EVENT NAME !!!!!! " + self.event_name)
+ if self.state == "reward_available" or self.state == "standby" or self.state == "initiate":
+ pass
+ else:
+ self.early_lick_error = True
+ self.error_repeat = True
+ self.restart()
+ if self.state == "standby":
+ pass
+ elif self.state == "initiate":
+ self.distance_diff = self.get_distance() - self.distance_buffer
+ if self.distance_diff >= self.distance_initiation:
+ self.initiate_error = False
+ self.start_cue()
+ else:
+ self.initiate_error = True
+ elif self.state == "cue_state":
+ self.distance_diff = self.get_distance() - self.distance_buffer
+ if self.distance_diff >= self.distance_cue:
+ self.cue_state_error = False
+ self.evaluate_reward()
+ else:
+ self.cue_state_error = True
+ elif self.state == "reward_available":
+ cue_state = self.current_card[0]
+ side_mice = None
+ if self.event_name == "left_entry":
+ side_mice = 'left'
+ self.left_poke_count += 1
+ self.left_poke_count_list.append(self.left_poke_count)
+ self.timeline_left_poke.append(time.time())
+ elif self.event_name == "right_entry":
+ side_mice = 'right'
+ self.right_poke_count += 1
+ self.right_poke_count_list.append(self.right_poke_count)
+ self.timeline_right_poke.append(time.time())
+ if side_mice:
+ self.side_mice_buffer = side_mice
+ self.cue_state = cue_state # cue state for foraging
+ if cue_state == 'all':
+ side_choice = side_mice
+ if side_choice == 'left':
+ self.pump_num = self.current_card[2][0]
+ self.reward_size = self.current_reward[0]
+ print("self.current_reward[0]: " + str(self.current_reward[0]))
+ elif side_choice == 'right':
+ self.pump_num = self.current_card[2][1]
+ self.reward_size = self.current_reward[1]
+ print("self.current_reward[0]: " + str(self.current_reward[1]))
+ elif cue_state == 'LED_L':
+ side_choice = self.current_card[1]
+ self.pump_num = self.current_card[2]
+ self.reward_size = self.current_reward[0]
+ elif cue_state == 'LED_R':
+ side_choice = self.current_card[1]
+ self.pump_num = self.current_card[2]
+ self.reward_size = self.current_reward[1]
+ print("!!!!!!!!CUE_STATE: " + str(cue_state))
+ if side_mice == side_choice: # if the animal chose correctly
+ self.side_mice_buffer = side_mice
+ if side_mice == side_choice: # if the animal chose correctly
+ if self.lick_count == 0: # if this is the first lick
+ self.side_choice = side_choice # foraging task
+ self.wrong_choice_error = False
+ self.reward_check = True
+ self.lick_count += 1
+ self.restart()
+ elif self.side_mice_buffer:
+ if self.lick_count == 0:
+ self.wrong_choice_error = True
+ self.lick_count += 1
+ self.restart()
+
+ # look for keystrokes
+ self.box.check_keybd()
+
+ def enter_standby(self):
+ logging.info(";" + str(time.time()) + ";[transition];enter_standby;" + str(self.error_repeat))
+ self.update_plot_choice()
+ # self.update_plot_error()
+ self.trial_running = False
+ # self.reward_error = False
+ if self.early_lick_error:
+ self.error_list.append("early_lick_error")
+ logging.info(";" + str(time.time()) + ";[error];early_lick_error;" + str(self.error_repeat))
+ self.check_cue('sound2')
+ self.early_lick_error = False
+ print(str(time.time()) + ", Total reward up till current session: " + str(self.total_reward))
+ logging.info(";" + str(time.time()) + ";[trial];trial_" + str(self.actual_trial_number) + ";" + str(self.error_repeat))
+
+ def exit_standby(self):
+ logging.info(";" + str(time.time()) + ";[transition];exit_standby;" + str(self.error_repeat))
+ self.lick_count = 0
+ self.side_mice_buffer = None
+ self.box.event_list.clear()
+ pass
+
+ def enter_initiate(self):
+ # print("!!!!!!!!!!!event name is " + self.event_name) # for debugging purposes
+ # check error_repeat
+ logging.info(";" + str(time.time()) + ";[transition];enter_initiate;" + str(self.error_repeat))
+ self.check_cue('sound1')
+ self.trial_running = True
+ # wait for treadmill signal and process the treadmill signal
+ self.distance_buffer = self.get_distance()
+ logging.info(
+ ";" + str(time.time()) + ";[treadmill];" + str(self.distance_buffer) + ";" + str(self.error_repeat))
+
+ def exit_initiate(self):
+ # check the flag to see whether to shuffle or keep the original card
+ logging.info(";" + str(time.time()) + ";[transition];exit_initiate;" + str(self.error_repeat))
+ print("EVENT NAME: " + str(self.box.event_list))
+ self.cue_off('sound1')
+ if self.initiate_error:
+ self.error_list.append('initiate_error')
+ self.error_repeat = True
+ logging.info(";" + str(time.time()) + ";[error];initiate_error;" + str(self.error_repeat))
+ self.error_count += 1
+
+ def enter_cue_state(self):
+ logging.info(";" + str(time.time()) + ";[transition];enter_cue_state;" + str(self.error_repeat))
+ # turn on the cue according to the current card
+ self.check_cue(self.current_card[0])
+ # wait for treadmill signal and process the treadmill signal
+ self.distance_buffer = self.get_distance()
+ logging.info(
+ ";" + str(time.time()) + ";[treadmill];" + str(self.distance_buffer) + ";" + str(self.error_repeat))
+
+ def exit_cue_state(self):
+ logging.info(";" + str(time.time()) + ";[transition];exit_cue_state;" + str(self.error_repeat))
+ self.cue_off(self.current_card[0])
+ if not self.early_lick_error:
+ if self.cue_state_error:
+ self.check_cue("sound2")
+ self.error_list.append('cue_state_error')
+ self.error_repeat = True
+ logging.info(";" + str(time.time()) + ";[error];cue_state_error;" + str(self.error_repeat))
+ self.error_count += 1
+ self.cue_state_error = False
+
+ def enter_reward_available(self):
+ logging.info(";" + str(time.time()) + ";[transition];enter_reward_available;" + str(self.error_repeat))
+ print(str(time.time()) + ", " + str(self.actual_trial_number) + ", cue_state distance satisfied")
+
+ def exit_reward_available(self):
+ logging.info(";" + str(time.time()) + ";[transition];exit_reward_available;" + str(self.error_repeat))
+ if self.lick_count == 0:
+ logging.info(";" + str(time.time()) + ";[error];no_choice_error;" + str(self.error_repeat))
+ self.check_cue('sound2')
+ self.error_repeat = True
+ self.error_count += 1
+ self.error_list.append('no_choice_error')
+ elif self.wrong_choice_error:
+ logging.info(";" + str(time.time()) + ";[error];wrong_choice_error;" + str(self.error_repeat))
+ self.check_cue('sound2')
+ self.error_repeat = True
+ self.error_count += 1
+ self.error_list.append('wrong_choice_error')
+ elif self.reward_check:
+ logging.info(";" + str(time.time()) + ";[error];correct_trial;" + str(self.error_repeat))
+ self.pump.reward(self.pump_num, self.reward_size)
+ self.error_repeat = False
+ self.total_reward += 1
+ self.reward_check = False
+ self.error_list.append('correct_trial')
+ self.pump_num = None
+ self.reward_size = None
+ self.wrong_choice_error = False
+
+
+ def check_cue(self, cue):
+ if cue == 'sound1':
+ logging.info(";" + str(time.time()) + ";[cue];cue_sound1_on;" + str(self.error_repeat))
+ self.box.sound1.on()
+ if cue == 'sound2':
+ logging.info(";" + str(time.time()) + ";[cue];cue_sound2_on;" + str(self.error_repeat))
+ self.box.sound2.blink(1, 0.1, 1)
+ elif cue == 'LED_L':
+ self.box.cueLED1.on()
+ logging.info(";" + str(time.time()) + ";[cue];cueLED_L_on;" + str(self.error_repeat))
+ elif cue == 'LED_R':
+ self.box.cueLED2.on()
+ logging.info(";" + str(time.time()) + ";[cue];cueLED_R_on;" + str(self.error_repeat))
+ elif cue == 'all':
+ self.box.cueLED1.on()
+ self.box.cueLED2.on()
+ logging.info(";" + str(time.time()) + ";[cue];LED_L+R_on; " + str(self.error_repeat))
+
+ def cue_off(self, cue):
+ if cue == 'all':
+ self.box.cueLED1.off()
+ self.box.cueLED2.off()
+ elif cue == 'sound1':
+ self.box.sound1.off()
+ logging.info(";" + str(time.time()) + ";[cue];cue_sound1_off;" + str(self.error_repeat))
+ elif cue == 'sound2':
+ self.box.sound2.off()
+ logging.info(";" + str(time.time()) + ";[cue];cue_sound2_off;" + str(self.error_repeat))
+ elif cue == 'LED_L':
+ self.box.cueLED1.off()
+ logging.info(";" + str(time.time()) + ";[cue];cueLED1_off;" + str(self.error_repeat))
+ elif cue == 'LED_R':
+ self.box.cueLED2.off()
+ logging.info(";" + str(time.time()) + ";[cue];cueLED2_off;" + str(self.error_repeat))
+
+ def get_distance(self):
+ try:
+ distance = self.treadmill.distance_cm
+ except Exception as e:
+ logging.info(";" + str(time.time()) + ";[system_error];" + str(e) + ";" + str(self.error_repeat))
+ self.treadmill = self.box.treadmill
+ distance = self.treadmill.distance_cm
+ return distance
+
+ def update_plot(self):
+ fig, axes = plt.subplots(1, 1, )
+ axes.plot([1, 2], [1, 2], color='green', label='test')
+ self.box.check_plot(fig)
+
+ def update_plot_error(self):
+ error_event = self.error_list
+ labels, counts = np.unique(error_event, return_counts=True)
+ ticks = range(len(counts))
+ fig, ax = plt.subplots(1, 1, )
+ ax.bar(ticks, counts, align='center', tick_label=labels)
+ ax = plt.gca()
+ ax.set_xticks(ticks, labels)
+ ax.set_xticklabels(labels=labels, rotation=70)
+
+ self.box.check_plot(fig)
+
+ def update_plot_choice(self, save_fig=False):
+ trajectory_left = self.left_poke_count_list
+ time_left = self.timeline_left_poke
+ trajectory_right = self.right_poke_count_list
+ time_right = self.timeline_right_poke
+ fig, ax = plt.subplots(1, 1, )
+ print(type(fig))
+
+ ax.plot(time_left, trajectory_left, color='b', marker="o", label='left_lick_trajectory')
+ ax.plot(time_right, trajectory_right, color='r', marker="o", label='right_lick_trajectory')
+ if save_fig:
+ plt.savefig(self.session_info['basedir'] + "/" + self.session_info['basename'] + "/" + \
+ self.session_info['basename'] + "_choice_plot" + '.png')
+ self.box.check_plot(fig)
+
+ def integrate_plot(self, save_fig=False):
+
+ fig, ax = plt.subplots(2, 1)
+
+ trajectory_left = self.left_poke_count_list
+ time_left = self.timeline_left_poke
+ trajectory_right = self.right_poke_count_list
+ time_right = self.timeline_right_poke
+ print(type(fig))
+
+ ax[0].plot(time_left, trajectory_left, color='b', marker="o", label='left_lick_trajectory')
+ ax[0].plot(time_right, trajectory_right, color='r', marker="o", label='right_lick_trajectory')
+
+ error_event = self.error_list
+ labels, counts = np.unique(error_event, return_counts=True)
+ ticks = range(len(counts))
+ ax[1].bar(ticks, counts, align='center', tick_label=labels)
+ # plt.xticks(ticks, labels)
+ # plt.title(session_name)
+ ax[1] = plt.gca()
+ ax[1].set_xticks(ticks, labels)
+ ax[1].set_xticklabels(labels=labels, rotation=70)
+
+ if save_fig:
+ plt.savefig(self.session_info['basedir'] + "/" + self.session_info['basename'] + "/" + \
+ self.session_info['basename'] + "_summery" + '.png')
+ self.box.check_plot(fig)
+
+ ########################################################################
+ # methods to start and end the behavioral session
+ ########################################################################
+
+ def start_session(self):
+ ic("TODO: start video")
+ self.box.video_start()
+
+ def end_session(self):
+ ic("TODO: stop video")
+ self.update_plot_choice(save_fig=True)
+ self.box.video_stop()
\ No newline at end of file
diff --git a/task_protocol/headfixed_task/run_headfixed_independent_reward_task.py b/task_protocol/headfixed_task/run_headfixed_independent_reward_task.py
new file mode 100644
index 0000000..1957312
--- /dev/null
+++ b/task_protocol/headfixed_task/run_headfixed_independent_reward_task.py
@@ -0,0 +1,265 @@
+#!/usr/bin/env -S ipython3 -i
+# run_headfixed2FC_task.py
+"""
+author: tian qiu & Soyoun Kim
+date: 2023-02-16
+name: run_headfixed_independent_reward_task.py
+goal: model_free reinforcement learning behavioral training run task file
+description:
+ an updated test version of run_headfixed_task.py & add foraging task
+
+"""
+import random
+import numpy as np
+from transitions import Machine
+from transitions import State
+from icecream import ic
+import logging
+from datetime import datetime
+import os
+import logging.config
+import pysistence, collections
+import socket
+import importlib
+import colorama
+import warnings
+import scipy.io, pickle
+import pygame
+from colorama import Fore, Style
+import time
+from time import sleep
+
+debug_enable = False
+
+# all modules above this line will have logging disabled
+logging.config.dictConfig({
+ 'version': 1,
+ 'disable_existing_loggers': True,
+})
+
+if debug_enable:
+ # enabling debugger
+ from IPython import get_ipython
+
+ ipython = get_ipython()
+ ipython.magic("pdb on")
+ ipython.magic("xmode Verbose")
+
+# import your task class here
+from headfixed_independent_reward_task import HeadfixedIndependentRewardTask
+
+try:
+ # load in session_info file, check that dates are correct, put in automatic
+ # time and date stamps for when the experiment was run
+
+ datestr = datetime.now().strftime("%Y-%m-%d")
+ timestr = datetime.now().strftime('%H%M%S')
+ full_module_name = 'session_info_' + datestr
+
+ import sys
+
+ session_info_path = '/home/pi/experiment_info/headfixed_independent_reward_task/session_info'
+ sys.path.insert(0, session_info_path)
+ tempmod = importlib.import_module(full_module_name)
+ session_info = tempmod.session_info
+ mouse_info = tempmod.mouse_info
+
+ session_info['date'] = datestr
+ session_info['time'] = timestr
+ session_info['datetime'] = session_info['date'] + '_' + session_info['time']
+ session_info['basename'] = session_info['mouse_name'] + '_' + session_info['datetime']
+ session_info['dir_name'] = session_info['basedir'] + "/" + session_info['basename']
+
+ if session_info['manual_date'] != session_info['date']: # check if file is updated
+ print('wrong date!!')
+ raise RuntimeError('manual_date field in session_info file is not updated')
+
+ # make data directory and initialize logfile
+ os.makedirs(session_info['dir_name'])
+ os.chdir(session_info['dir_name'])
+ session_info['file_basename'] = session_info['dir_name'] + '/' + session_info['basename']
+
+ logging.basicConfig(
+ level=logging.INFO,
+ format="%(asctime)s.%(msecs)03d,[%(levelname)s],%(message)s",
+ datefmt=('%H:%M:%S'),
+ handlers=[
+ logging.FileHandler(session_info['file_basename'] + '.log'),
+ logging.StreamHandler() # sends copy of log output to screen
+ ]
+ )
+
+ from task_information_independent_reward import TaskInformation
+ task_information = TaskInformation()
+ # print("Imported task_information_headfixed: " + str(task_information.name))
+ task = HeadfixedIndependentRewardTask(name="headfixed_independent_reward_task", session_info=session_info)
+
+
+ def cumsum_positive(input_list):
+ for index in range(len(input_list)):
+ if index == 0 and input_list[index] < 0:
+ input_list[index] = -input_list[index]
+ elif input_list[index] + input_list[index - 1] < 0:
+ input_list[index] = input_list[index] - input_list[index - 1]
+ else:
+ input_list[index] = input_list[index] + input_list[index - 1]
+ return input_list
+
+ def generate_reward_trajectory(scale=0.5, offset=3.0, change_point=20, ntrials=200):
+ # initial reward (need to be random)
+ rewards_L = [1]
+ rewards_R = [1]
+ for a in np.arange(np.round(ntrials / change_point)):
+ temp = np.random.randn(change_point) * scale
+ rewards_L.append(cumsum_positive(temp) + offset)
+ temp = np.random.randn(change_point) * scale
+ rewards_R.append(cumsum_positive(temp) + offset)
+ rewards_L = np.hstack(rewards_L)
+ rewards_R = np.hstack(rewards_R)
+ # plt.plot(rewards_L,'b');plt.plot(rewards_R,'r--')
+ reward_LR = [rewards_L, rewards_R]
+ reward_LR = np.transpose(np.array(reward_LR))
+ reward_LR = reward_LR[0:ntrials, :]
+ # print(reward_LR)
+ return reward_LR
+
+ def generate_sine_wave(increment, period_width, amplitude_offset, amplitude_scale, deviation, session_length): # for training purpose only
+ session_start = random.uniform(0, period_width)
+ session_end = session_start + session_length
+ value_input = np.arange(session_start, session_end, increment)
+
+ sine_output = (np.sin((np.pi / period_width) * value_input) + amplitude_offset) * amplitude_scale
+ negative_sine_output = (np.sin((np.pi / period_width) * -value_input) + amplitude_offset) * amplitude_scale
+ left_side_reward = np.random.normal(sine_output, deviation)
+ right_side_reward = np.random.normal(negative_sine_output, deviation)
+ reward_list = list(zip(left_side_reward, right_side_reward))
+ return reward_list
+
+ if session_info['phase'] == "independent_reward":
+ # from reward_distribution import generate_reward_trajectory
+ scale = session_info['independent_reward']['scale']
+ offset = session_info['independent_reward']['offset']
+ change_point = session_info['independent_reward']['change_point']
+ ntrials = session_info['independent_reward']['ntrials']
+ reward_distribution_list = generate_reward_trajectory(scale, offset, change_point, ntrials)
+ elif session_info['phase'] == "forced_choice":
+ reward_size = session_info['reward_size']
+ elif session_info['phase'] == "sine_reward":
+ session_length = session_info["sine_reward"]["session_length"]
+ increment = session_info["sine_reward"]["increment"]
+ period_width = session_info["sine_reward"]["period_width"]
+ amplitude_offset = session_info["sine_reward"]["amplitude_offset"]
+ amplitude_scale = session_info["sine_reward"]["amplitude_scale"]
+ deviation = session_info["sine_reward"]["deviation"]
+ reward_distribution_list = generate_sine_wave(increment, period_width, amplitude_offset,
+ amplitude_scale, deviation, session_length)
+ elif session_info['phase'] == 'foraging_reward':
+ offset = session_info['foraging_reward']['offset']
+ max_reward = session_info['foraging_reward']['max_reward']
+ increment = session_info['foraging_reward']['increment']
+ reward_distribution = (3,3)
+
+
+ first_trial_of_the_session = True
+
+ # # you can change various parameters if you want
+ # task.machine.states['cue'].timeout = 2
+
+ # start session
+ task.start_session()
+ scipy.io.savemat(session_info['file_basename'] + '_session_info.mat', {'session_info': session_info})
+ pickle.dump(session_info, open(session_info['file_basename'] + '_session_info.pkl', "wb"))
+ sleep(10)
+ # loop over trials
+ # Set a timer
+ t_minute = int(input("Enter the time in minutes: ")) # wll add in the session info
+ t_end = time.time() + 60 * t_minute
+ while time.time() < t_end: # time check
+ if task.error_repeat: # error repeat check
+ task.error_repeat = False
+ print("punishment_time_out: " + str(session_info["punishment_timeout"]))
+ sleep(session_info["punishment_timeout"])
+ print("Trial " + str(task.actual_trial_number) + " \n")
+ task.actual_trial_number += 1
+ print("*******************************\n")
+ print("*error_repeat trial* \n" +
+ " - Current card condition: \n" +
+ "*******************************\n" +
+ "*reward_side: " + str(task.current_card[0]) + "\n" +
+ "*reward_size: " + str(task.current_reward)[1:-1] + "\n")
+ else:
+ if not first_trial_of_the_session:
+ print("reward_time_out: " + str(session_info["reward_timeout"]))
+ sleep(session_info["reward_timeout"])
+ else:
+ first_trial_of_the_session = False
+ # setup the beginning of a new trial
+ task.error_count = 0 # reset the error count if previous trial is correct
+ print("Trial " + str(task.actual_trial_number) + " \n")
+ task.correct_trial_number += 1
+ task.actual_trial_number += 1
+ print("*******************************\n")
+ # acquire new reward contingency and cue association
+ #print("fraction " + str(session_info['fraction']) + " \n")
+ task.current_card = task_information.draw_card(session_info['phase'], session_info['fraction'])
+ if session_info['phase'] == "independent_reward":
+ task.current_reward = reward_distribution_list[task.correct_trial_number] + float(task.reward_size_offset)
+ elif session_info['phase'] == "forced_choice":
+ task.current_reward = session_info['reward_size']
+ elif session_info['phase'] == "sine_reward":
+ task.current_reward = reward_distribution_list[task.correct_trial_number]
+ elif session_info['phase'] == 'foraging_reward':
+ reward_L = reward_distribution[0]
+ reward_R = reward_distribution[1]
+ task.current_reward = reward_distribution
+ if task.cue_state == 'all':
+ if task.side_choice == 'left':
+ reward_L = reward_L - increment
+ reward_R = reward_R + increment
+ if reward_L < 0:
+ reward_L = 0
+ if reward_R > max_reward:
+ reward_R = max_reward
+ elif task.side_choice == 'right':
+ reward_R = reward_R - increment
+ reward_L = reward_L + increment
+ if reward_R < 0:
+ reward_R = 0
+ if reward_L > max_reward:
+ reward_L = max_reward
+ reward_distribution = (reward_L, reward_R)
+ task.current_reward = reward_distribution
+
+
+ logging.info(";" + str(time.time()) + ";[condition];current_card_" + str(task.current_card) +
+ ";current_reward_" + str(task.current_reward)[1:-1])
+
+ print(" - Current card condition: \n" +
+ "*******************************\n" +
+ "*reward_side: " + str(task.current_card[0]) + "\n" +
+ "*reward_size: " + str(task.current_reward)[1:-1] + "\n")
+ logging.info(";" + str(time.time()) + ";[transition];start_trial()")
+ task.start_trial() # initiate the time state machine, start_trial() is a trigger
+ while task.trial_running:
+ task.run() # run command trigger additional functions outside of the state machine
+ print("error_count: " + str(task.error_count))
+ raise SystemExit
+
+# graceful exit
+except (KeyboardInterrupt, SystemExit):
+ print(Fore.RED + Style.BRIGHT + 'Exiting now...' + Style.RESET_ALL)
+ ic('about to call end_session()')
+ task.end_session()
+ ic('just called end_session()')
+ # save dicts to disk
+ scipy.io.savemat(session_info['file_basename'] + '_session_info.mat', {'session_info': session_info})
+ pickle.dump(session_info, open(session_info['file_basename'] + '_session_info.pkl', "wb"))
+ pygame.quit()
+
+# exit because of error
+except RuntimeError as ex:
+ print(Fore.RED + Style.BRIGHT + 'ERROR: Exiting now' + Style.RESET_ALL)
+ # save dicts to disk
+ scipy.io.savemat(session_info['file_basename'] + '_session_info.mat', {'session_info': session_info})
+ pickle.dump(session_info, open(session_info['file_basename'] + '_session_info.pkl', "wb"))
+ task.end_session()
\ No newline at end of file
diff --git a/task_protocol/headfixed_task/run_headfixed_task.py b/task_protocol/headfixed_task/run_headfixed_task.py
new file mode 100644
index 0000000..be08437
--- /dev/null
+++ b/task_protocol/headfixed_task/run_headfixed_task.py
@@ -0,0 +1,265 @@
+#!/usr/bin/env -S ipython3 -i
+# run_headfixed2FC_task.py
+"""
+author: tian qiu & Soyoun Kim
+date: 2023-02-16
+name: run_headfixed_independent_reward_task.py
+goal: model_free reinforcement learning behavioral training run task file
+description:
+ an updated test version of run_headfixed_task.py & add foraging task
+
+"""
+import random
+import numpy as np
+from transitions import Machine
+from transitions import State
+from icecream import ic
+import logging
+from datetime import datetime
+import os
+import logging.config
+import pysistence, collections
+import socket
+import importlib
+import colorama
+import warnings
+import scipy.io, pickle
+import pygame
+from colorama import Fore, Style
+import time
+from time import sleep
+
+debug_enable = False
+
+# all modules above this line will have logging disabled
+logging.config.dictConfig({
+ 'version': 1,
+ 'disable_existing_loggers': True,
+})
+
+if debug_enable:
+ # enabling debugger
+ from IPython import get_ipython
+
+ ipython = get_ipython()
+ ipython.magic("pdb on")
+ ipython.magic("xmode Verbose")
+
+# import your task class here
+from headfixed_task import HeadfixedTask
+
+try:
+ # load in session_info file, check that dates are correct, put in automatic
+ # time and date stamps for when the experiment was run
+
+ datestr = datetime.now().strftime("%Y-%m-%d")
+ timestr = datetime.now().strftime('%H%M%S')
+ full_module_name = 'session_info_' + datestr
+
+ import sys
+
+ session_info_path = '/home/pi/experiment_info/headfixed_task/session_info'
+ sys.path.insert(0, session_info_path)
+ tempmod = importlib.import_module(full_module_name)
+ session_info = tempmod.session_info
+ mouse_info = tempmod.mouse_info
+
+ session_info['date'] = datestr
+ session_info['time'] = timestr
+ session_info['datetime'] = session_info['date'] + '_' + session_info['time']
+ session_info['basename'] = session_info['mouse_name'] + '_' + session_info['datetime']
+ session_info['dir_name'] = session_info['basedir'] + "/" + session_info['basename']
+
+ if session_info['manual_date'] != session_info['date']: # check if file is updated
+ print('wrong date!!')
+ raise RuntimeError('manual_date field in session_info file is not updated')
+
+ # make data directory and initialize logfile
+ os.makedirs(session_info['dir_name'])
+ os.chdir(session_info['dir_name'])
+ session_info['file_basename'] = session_info['dir_name'] + '/' + session_info['basename']
+
+ logging.basicConfig(
+ level=logging.INFO,
+ format="%(asctime)s.%(msecs)03d,[%(levelname)s],%(message)s",
+ datefmt=('%H:%M:%S'),
+ handlers=[
+ logging.FileHandler(session_info['file_basename'] + '.log'),
+ logging.StreamHandler() # sends copy of log output to screen
+ ]
+ )
+
+ from task_information_independent_reward import TaskInformation
+ task_information = TaskInformation()
+ # print("Imported task_information_headfixed: " + str(task_information.name))
+ task = HeadfixedTask(name="headfixed_task", session_info=session_info)
+
+
+ def cumsum_positive(input_list):
+ for index in range(len(input_list)):
+ if index == 0 and input_list[index] < 0:
+ input_list[index] = -input_list[index]
+ elif input_list[index] + input_list[index - 1] < 0:
+ input_list[index] = input_list[index] - input_list[index - 1]
+ else:
+ input_list[index] = input_list[index] + input_list[index - 1]
+ return input_list
+
+ def generate_reward_trajectory(scale=0.5, offset=3.0, change_point=20, ntrials=200):
+ # initial reward (need to be random)
+ rewards_L = [1]
+ rewards_R = [1]
+ for a in np.arange(np.round(ntrials / change_point)):
+ temp = np.random.randn(change_point) * scale
+ rewards_L.append(cumsum_positive(temp) + offset)
+ temp = np.random.randn(change_point) * scale
+ rewards_R.append(cumsum_positive(temp) + offset)
+ rewards_L = np.hstack(rewards_L)
+ rewards_R = np.hstack(rewards_R)
+ # plt.plot(rewards_L,'b');plt.plot(rewards_R,'r--')
+ reward_LR = [rewards_L, rewards_R]
+ reward_LR = np.transpose(np.array(reward_LR))
+ reward_LR = reward_LR[0:ntrials, :]
+ # print(reward_LR)
+ return reward_LR
+
+ def generate_sine_wave(increment, period_width, amplitude_offset, amplitude_scale, deviation, session_length): # for training purpose only
+ session_start = random.uniform(0, period_width)
+ session_end = session_start + session_length
+ value_input = np.arange(session_start, session_end, increment)
+
+ sine_output = (np.sin((np.pi / period_width) * value_input) + amplitude_offset) * amplitude_scale
+ negative_sine_output = (np.sin((np.pi / period_width) * -value_input) + amplitude_offset) * amplitude_scale
+ left_side_reward = np.random.normal(sine_output, deviation)
+ right_side_reward = np.random.normal(negative_sine_output, deviation)
+ reward_list = list(zip(left_side_reward, right_side_reward))
+ return reward_list
+
+ if session_info['phase'] == "independent_reward":
+ # from reward_distribution import generate_reward_trajectory
+ scale = session_info['independent_reward']['scale']
+ offset = session_info['independent_reward']['offset']
+ change_point = session_info['independent_reward']['change_point']
+ ntrials = session_info['independent_reward']['ntrials']
+ reward_distribution_list = generate_reward_trajectory(scale, offset, change_point, ntrials)
+ elif session_info['phase'] == "forced_choice":
+ reward_size = session_info['reward_size']
+ elif session_info['phase'] == "sine_reward":
+ session_length = session_info["sine_reward"]["session_length"]
+ increment = session_info["sine_reward"]["increment"]
+ period_width = session_info["sine_reward"]["period_width"]
+ amplitude_offset = session_info["sine_reward"]["amplitude_offset"]
+ amplitude_scale = session_info["sine_reward"]["amplitude_scale"]
+ deviation = session_info["sine_reward"]["deviation"]
+ reward_distribution_list = generate_sine_wave(increment, period_width, amplitude_offset,
+ amplitude_scale, deviation, session_length)
+ elif session_info['phase'] == 'foraging_reward':
+ offset = session_info['foraging_reward']['offset']
+ max_reward = session_info['foraging_reward']['max_reward']
+ increment = session_info['foraging_reward']['increment']
+ reward_distribution = (3,3)
+
+
+ first_trial_of_the_session = True
+
+ # # you can change various parameters if you want
+ # task.machine.states['cue'].timeout = 2
+
+ # start session
+ task.start_session()
+ scipy.io.savemat(session_info['file_basename'] + '_session_info.mat', {'session_info': session_info})
+ pickle.dump(session_info, open(session_info['file_basename'] + '_session_info.pkl', "wb"))
+ sleep(10)
+ # loop over trials
+ # Set a timer
+ t_minute = int(input("Enter the time in minutes: ")) # wll add in the session info
+ t_end = time.time() + 60 * t_minute
+ while time.time() < t_end: # time check
+ if task.error_repeat: # error repeat check
+ task.error_repeat = False
+ print("punishment_time_out: " + str(session_info["punishment_timeout"]))
+ sleep(session_info["punishment_timeout"])
+ print("Trial " + str(task.actual_trial_number) + " \n")
+ task.actual_trial_number += 1
+ print("*******************************\n")
+ print("*error_repeat trial* \n" +
+ " - Current card condition: \n" +
+ "*******************************\n" +
+ "*reward_side: " + str(task.current_card[0]) + "\n" +
+ "*reward_size: " + str(task.current_reward)[1:-1] + "\n")
+ else:
+ if not first_trial_of_the_session:
+ print("reward_time_out: " + str(session_info["reward_timeout"]))
+ sleep(session_info["reward_timeout"])
+ else:
+ first_trial_of_the_session = False
+ # setup the beginning of a new trial
+ task.error_count = 0 # reset the error count if previous trial is correct
+ print("Trial " + str(task.actual_trial_number) + " \n")
+ task.correct_trial_number += 1
+ task.actual_trial_number += 1
+ print("*******************************\n")
+ # acquire new reward contingency and cue association
+ #print("fraction " + str(session_info['fraction']) + " \n")
+ task.current_card = task_information.draw_card(session_info['phase'], session_info['fraction'])
+ if session_info['phase'] == "independent_reward":
+ task.current_reward = reward_distribution_list[task.correct_trial_number] + float(task.reward_size_offset)
+ elif session_info['phase'] == "forced_choice":
+ task.current_reward = session_info['reward_size']
+ elif session_info['phase'] == "sine_reward":
+ task.current_reward = reward_distribution_list[task.correct_trial_number]
+ elif session_info['phase'] == 'foraging_reward':
+ reward_L = reward_distribution[0]
+ reward_R = reward_distribution[1]
+ task.current_reward = reward_distribution
+ if task.cue_state == 'all':
+ if task.side_choice == 'left':
+ reward_L = reward_L - increment
+ reward_R = reward_R + increment
+ if reward_L < 0:
+ reward_L = 0
+ if reward_R > max_reward:
+ reward_R = max_reward
+ elif task.side_choice == 'right':
+ reward_R = reward_R - increment
+ reward_L = reward_L + increment
+ if reward_R < 0:
+ reward_R = 0
+ if reward_L > max_reward:
+ reward_L = max_reward
+ reward_distribution = (reward_L, reward_R)
+ task.current_reward = reward_distribution
+
+
+ logging.info(";" + str(time.time()) + ";[condition];current_card_" + str(task.current_card) +
+ ";current_reward_" + str(task.current_reward)[1:-1])
+
+ print(" - Current card condition: \n" +
+ "*******************************\n" +
+ "*reward_side: " + str(task.current_card[0]) + "\n" +
+ "*reward_size: " + str(task.current_reward)[1:-1] + "\n")
+ logging.info(";" + str(time.time()) + ";[transition];start_trial()")
+ task.start_trial() # initiate the time state machine, start_trial() is a trigger
+ while task.trial_running:
+ task.run() # run command trigger additional functions outside of the state machine
+ print("error_count: " + str(task.error_count))
+ raise SystemExit
+
+# graceful exit
+except (KeyboardInterrupt, SystemExit):
+ print(Fore.RED + Style.BRIGHT + 'Exiting now...' + Style.RESET_ALL)
+ ic('about to call end_session()')
+ task.end_session()
+ ic('just called end_session()')
+ # save dicts to disk
+ scipy.io.savemat(session_info['file_basename'] + '_session_info.mat', {'session_info': session_info})
+ pickle.dump(session_info, open(session_info['file_basename'] + '_session_info.pkl', "wb"))
+ pygame.quit()
+
+# exit because of error
+except RuntimeError as ex:
+ print(Fore.RED + Style.BRIGHT + 'ERROR: Exiting now' + Style.RESET_ALL)
+ # save dicts to disk
+ scipy.io.savemat(session_info['file_basename'] + '_session_info.mat', {'session_info': session_info})
+ pickle.dump(session_info, open(session_info['file_basename'] + '_session_info.pkl', "wb"))
+ task.end_session()
\ No newline at end of file
diff --git a/task_protocol/headfixed_task/session_info_headfixed_independent_reward.py b/task_protocol/headfixed_task/session_info_headfixed_independent_reward.py
new file mode 100644
index 0000000..4c4bbf1
--- /dev/null
+++ b/task_protocol/headfixed_task/session_info_headfixed_independent_reward.py
@@ -0,0 +1,130 @@
+from datetime import datetime
+import os
+import pysistence, collections
+import socket
+import pandas as pd
+import numpy as np
+
+# defining immutable mouse dict (once defined for a mouse, NEVER EDIT IT)
+mouse_info = pysistence.make_dict({'mouse_name': 'test',
+ 'fake_field': 'fake_info',
+ })
+
+# Information for this session (the user should edit this each session)
+session_info = collections.OrderedDict()
+session_info['mouse_info'] = mouse_info
+session_info['mouse_name'] = mouse_info['mouse_name']
+
+session_info['basedir'] = '/home/pi/buffer'
+session_info['external_storage'] = '/mnt/hd'
+session_info['flipper_filename'] = '/home/pi/buffer/flipper_timestamp'
+# for actual data save to this dir:
+# session_info['basedir'] = '/home/pi/video'
+session_info['weight'] = 0.0
+session_info['manual_date'] = '2023-07-13'
+session_info['box_name'] = socket.gethostname()
+session_info['block_number'] = 1 # 1 (left large) or 2 (right large) which block starts
+
+session_info['config'] = 'headfixed2FC'
+
+# behavior parameters
+session_info['timeout_length'] = 5 # in seconds
+session_info["lick_threshold"] = 1
+# visual stimulus
+session_info["visual_stimulus"] = False
+
+session_info['config'] = 'headfixed2FC'
+session_info['treadmill_setup'] = {}
+session_info['treadmill'] = True
+session_info['fraction'] = 0.3 # 0.3, 0.5,0.7,1 # free choice fraction 1 for all free choice
+session_info['phase'] = 'foraging_reward' # 'forced_choice', 'sine_reward'
+
+
+
+if session_info['treadmill']:
+ session_info['treadmill_setup']['distance_cue'] = 5 # cm
+ session_info['treadmill_setup']['distance_initiation'] = 10 # cm
+else:
+ session_info['treadmill_setup'] = None
+
+session_info['error_repeat'] = True
+if session_info['error_repeat']:
+ session_info['error_max'] = 3
+
+# condition setup
+session_info['cue'] = ['LED_L', 'LED_R', 'all']
+# session_info['state'] = ['block1', 'block2'] #
+session_info['choice'] = ['right', 'left'] # lick port
+session_info['air_duration'] = 0
+session_info["vacuum_duration"] = 1
+
+""" solenoid calibration information configuration """
+
+solenoid_coeff = None
+def get_coefficient():
+ df_calibration = pd.read_csv("~/experiment_info/calibration_info/calibration.csv")
+ pump_coefficient = {}
+
+ for pump_num in range(1, 5):
+ df_pump = df_calibration[df_calibration['pump_number'] == pump_num]
+ mg_per_pulse = df_pump['weight_fluid'].div(df_pump['iteration'])
+ on_time = df_pump['on_time']
+
+ fit_calibration = np.polyfit(mg_per_pulse, on_time, 1) # output with highest power first
+ pump_coefficient[str(pump_num)] = fit_calibration
+ return pump_coefficient
+
+try:
+ solenoid_coeff = get_coefficient()
+except Exception as e:
+ print(e)
+
+session_info["calibration_coefficient"] = {}
+
+if solenoid_coeff:
+ session_info["calibration_coefficient"]['1'] = solenoid_coeff["1"]
+ session_info["calibration_coefficient"]['2'] = solenoid_coeff["2"]
+ session_info["calibration_coefficient"]['3'] = solenoid_coeff["3"]
+ session_info["calibration_coefficient"]['4'] = solenoid_coeff["4"]
+else:
+ print("No coefficients, generate the default")
+ # solenoid valve linear fit coefficient for each pump
+ session_info["calibration_coefficient"]['1'] = [0.13, 0] # highest power first
+ session_info["calibration_coefficient"]['2'] = [0.13, 0]
+ session_info["calibration_coefficient"]['3'] = [0.13, 0.0]
+ session_info["calibration_coefficient"]['4'] = [0.13, 0.0]
+
+# define timeout during each condition
+session_info['initiation_timeout'] = 120 # s
+session_info['cue_timeout'] = 120
+session_info['wait_for_choice'] = 60
+session_info['reward_timeout'] = 1
+session_info["punishment_timeout"] = 3
+
+session_info["key_reward_amount"] = 2
+session_info['reward_size_offset'] = 2
+session_info['reward_size'] = (5, 5)
+
+if session_info["phase"] == 'independent_reward':
+ session_info['independent_reward'] = {}
+ session_info['independent_reward']['scale'] = 0.5
+ session_info['independent_reward']['offset'] = 3.0
+ session_info['independent_reward']['change_point'] = 20
+ session_info['independent_reward']['ntrials'] = 1000
+elif session_info["phase"] == 'sine_reward':
+ session_info["sine_reward"] = {}
+ session_info["sine_reward"]["increment"] = 1
+ session_info["sine_reward"]["period_width"] = 40
+ session_info["sine_reward"]["amplitude_offset"] = 2
+ session_info["sine_reward"]["amplitude_scale"] = 3
+ session_info["sine_reward"]["deviation"] = 0
+elif session_info['phase'] == 'foraging_reward':
+ session_info["foraging_reward"] = {}
+ session_info["foraging_reward"]["increment"] = 0.25
+ session_info["foraging_reward"]["offset"] = 3
+ session_info["foraging_reward"]["max_reward"] = 10
+
+
+session_info['consecutive_control'] = False
+if session_info['consecutive_control']:
+ session_info['consecutive_max'] = 3
\ No newline at end of file
diff --git a/task_protocol/headfixed_task/session_info_headfixed_task.py b/task_protocol/headfixed_task/session_info_headfixed_task.py
new file mode 100644
index 0000000..5b8795d
--- /dev/null
+++ b/task_protocol/headfixed_task/session_info_headfixed_task.py
@@ -0,0 +1,131 @@
+from datetime import datetime
+import os
+import pysistence, collections
+import socket
+import pandas as pd
+import numpy as np
+
+# defining immutable mouse dict (once defined for a mouse, NEVER EDIT IT)
+mouse_info = pysistence.make_dict({'mouse_name': 'test',
+ 'fake_field': 'fake_info',
+ })
+
+# Information for this session (the user should edit this each session)
+session_info = collections.OrderedDict()
+session_info['mouse_info'] = mouse_info
+session_info['mouse_name'] = mouse_info['mouse_name']
+
+session_info['basedir'] = '/home/pi/buffer'
+session_info['external_storage'] = '/mnt/hd'
+session_info['flipper_filename'] = '/home/pi/buffer/flipper_timestamp'
+# for actual data save to this dir:
+# session_info['basedir'] = '/home/pi/video'
+session_info['weight'] = 0.0
+session_info['manual_date'] = '2023-07-13'
+session_info['box_name'] = socket.gethostname()
+session_info['block_number'] = 1 # 1 (left large) or 2 (right large) which block starts
+
+session_info['config'] = 'headfixed2FC'
+
+# behavior parameters
+session_info['timeout_length'] = 5 # in seconds
+session_info["lick_threshold"] = 1
+# visual stimulus
+session_info["visual_stimulus"] = False
+
+session_info['config'] = 'headfixed2FC'
+session_info['treadmill_setup'] = {}
+session_info['treadmill'] = True
+session_info['fraction'] = 0.3 # 0.3, 0.5,0.7,1 # free choice fraction 1 for all free choice
+session_info['phase'] = 'foraging_reward' # 'forced_choice', 'sine_reward'
+
+
+
+if session_info['treadmill']:
+ session_info['treadmill_setup']['distance_cue'] = 5 # cm
+ session_info['treadmill_setup']['distance_initiation'] = 10 # cm
+else:
+ session_info['treadmill_setup'] = None
+
+session_info['error_repeat'] = True
+if session_info['error_repeat']:
+ session_info['error_max'] = 3
+
+# condition setup
+session_info['cue'] = ['LED_L', 'LED_R', 'all']
+# session_info['state'] = ['block1', 'block2'] #
+session_info['choice'] = ['right', 'left'] # lick port
+session_info['air_duration'] = 0
+session_info["vacuum_duration"] = 1
+
+""" solenoid calibration information configuration """
+
+solenoid_coeff = None
+def get_coefficient():
+ df_calibration = pd.read_csv("~/experiment_info/calibration_info/calibration.csv")
+ pump_coefficient = {}
+
+ for pump_num in range(1, 5):
+ df_pump = df_calibration[df_calibration['pump_number'] == pump_num]
+ mg_per_pulse = df_pump['weight_fluid'].div(df_pump['iteration'])
+ on_time = df_pump['on_time']
+
+ fit_calibration = np.polyfit(mg_per_pulse, on_time, 1) # output with highest power first
+ pump_coefficient[str(pump_num)] = fit_calibration
+ return pump_coefficient
+
+try:
+ solenoid_coeff = get_coefficient()
+except Exception as e:
+ print(e)
+
+session_info["calibration_coefficient"] = {}
+
+if solenoid_coeff:
+ session_info["calibration_coefficient"]['1'] = solenoid_coeff["1"]
+ session_info["calibration_coefficient"]['2'] = solenoid_coeff["2"]
+ session_info["calibration_coefficient"]['3'] = solenoid_coeff["3"]
+ session_info["calibration_coefficient"]['4'] = solenoid_coeff["4"]
+else:
+ print("No coefficients, generate the default")
+ # solenoid valve linear fit coefficient for each pump
+ session_info["calibration_coefficient"]['1'] = [0.13, 0] # highest power first
+ session_info["calibration_coefficient"]['2'] = [0.13, 0]
+ session_info["calibration_coefficient"]['3'] = [0.13, 0.0]
+ session_info["calibration_coefficient"]['4'] = [0.13, 0.0]
+
+# define timeout during each condition
+session_info['initiation_timeout'] = 120 # s
+session_info['cue_timeout'] = 120
+session_info['wait_for_choice'] = 60
+session_info['reward_timeout'] = 1
+session_info["punishment_timeout"] = 3
+
+session_info["key_reward_amount"] = 2
+session_info['reward_size_offset'] = 2
+session_info['reward_size'] = (5, 5)
+
+if session_info["phase"] == 'independent_reward':
+ session_info['independent_reward'] = {}
+ session_info['independent_reward']['scale'] = 0.5
+ session_info['independent_reward']['offset'] = 3.0
+ session_info['independent_reward']['change_point'] = 20
+ session_info['independent_reward']['ntrials'] = 1000
+elif session_info["phase"] == 'sine_reward':
+ session_info["sine_reward"] = {}
+ session_info["sine_reward"]["increment"] = 1
+ session_info["sine_reward"]["period_width"] = 40
+ session_info["sine_reward"]["amplitude_offset"] = 2
+ session_info["sine_reward"]["amplitude_scale"] = 3
+ session_info["sine_reward"]["deviation"] = 0
+elif session_info['phase'] == 'foraging_reward':
+ session_info["foraging_reward"] = {}
+ session_info["foraging_reward"]["increment"] = 0.25
+ session_info["foraging_reward"]["offset"] = 3
+ session_info["foraging_reward"]["max_reward"] = 10
+
+
+session_info['consecutive_control'] = False
+if session_info['consecutive_control']:
+ session_info['consecutive_max'] = 3
+
diff --git a/task_protocol/headfixed_task/task_information_headfixed.py b/task_protocol/headfixed_task/task_information_headfixed.py
new file mode 100644
index 0000000..ddcf184
--- /dev/null
+++ b/task_protocol/headfixed_task/task_information_headfixed.py
@@ -0,0 +1,46 @@
+import random
+
+
+class TaskInformation(object):
+ def __init__(self, **kwargs):
+ self.name = "model_based_reinforcement_learning_task"
+ self.deck = [('LED_L', 'left', '1'), ('LED_R', 'right', '2'),
+ ('LED_L', 'left', '1'), ('LED_R', 'right', '2'),
+ ('LED_L', 'left', '1'), ('LED_R', 'right', '2'),
+ ('LED_L', 'left', '1'), ('LED_R', 'right', '2'),
+ ('LED_L', 'left', '1'), ('LED_R', 'right', '2'),
+ ('all', ('left', 'right'), ('1', '2')), ('all', ('left', 'right'), ('1', '2')),
+ ('all', ('left', 'right'), ('1', '2')), ('all', ('left', 'right'), ('1', '2')),
+ ('all', ('left', 'right'), ('1', '2')), ('all', ('left', 'right'), ('1', '2')),
+ ('all', ('left', 'right'), ('1', '2')), ('all', ('left', 'right'), ('1', '2')),
+ ('all', ('left', 'right'), ('1', '2')), ('all', ('left', 'right'), ('1', '2')),
+ ]
+
+ def draw_card(self, phase="independent_reward", fraction=0.5):
+ row_start = 0
+ row_end = len(self.deck)-1
+
+ if phase == 'forced_choice':
+ row_end = 1
+ elif phase == 'free_choice':
+ row_start = 9
+ elif phase == 'forced_choice_left':
+ row_end = 0
+ elif phase == 'forced_choice_right':
+ row_start = 1
+ row_end = 1
+ else:
+ if fraction == 0.5:
+ row_start = 8
+ row_end = 11
+ elif fraction == 0.7:
+ row_start = 6
+ elif fraction == 0.3:
+ row_end = 13
+ elif fraction == 1:
+ row_start = 11
+
+ card = self.deck[random.randint(row_start, row_end)]
+ return card
+
+# print(TaskInformation().draw_card())
diff --git a/task_protocol/headfixed_task/task_information_independent_reward.py b/task_protocol/headfixed_task/task_information_independent_reward.py
new file mode 100644
index 0000000..a423b6d
--- /dev/null
+++ b/task_protocol/headfixed_task/task_information_independent_reward.py
@@ -0,0 +1,46 @@
+import random
+
+
+class TaskInformation(object):
+ def __init__(self, **kwargs):
+ self.name = "model_based_reinforcement_learning_task"
+ self.deck = [('LED_L', 'left', '1'), ('LED_R', 'right', '2'),
+ ('LED_L', 'left', '1'), ('LED_R', 'right', '2'),
+ ('LED_L', 'left', '1'), ('LED_R', 'right', '2'),
+ ('LED_L', 'left', '1'), ('LED_R', 'right', '2'),
+ ('LED_L', 'left', '1'), ('LED_R', 'right', '2'),
+ ('all', ('left', 'right'), ('1', '2')), ('all', ('left', 'right'), ('1', '2')),
+ ('all', ('left', 'right'), ('1', '2')), ('all', ('left', 'right'), ('1', '2')),
+ ('all', ('left', 'right'), ('1', '2')), ('all', ('left', 'right'), ('1', '2')),
+ ('all', ('left', 'right'), ('1', '2')), ('all', ('left', 'right'), ('1', '2')),
+ ('all', ('left', 'right'), ('1', '2')), ('all', ('left', 'right'), ('1', '2')),
+ ]
+
+ def draw_card(self, phase="independent_reward", fraction=0.5):
+ row_start = 0
+ row_end = len(self.deck)-1
+
+ if phase == 'forced_choice':
+ row_end = 1
+ elif phase == 'free_choice':
+ row_start = 9
+ elif phase == 'forced_choice_left':
+ row_end = 0
+ elif phase == 'forced_choice_right':
+ row_start = 1
+ row_end = 1
+ else:
+ if fraction == 0.5:
+ row_start = 8
+ row_end = 11
+ elif fraction == 0.7:
+ row_start = 6
+ elif fraction == 0.3:
+ row_end = 13
+ elif fraction == 1:
+ row_start = 11
+
+ card = self.deck[random.randint(row_start, row_end)]
+ return card
+
+# print(TaskInformation().draw_card())
\ No newline at end of file
diff --git a/task_protocol/kelly_task/__init__.py b/task_protocol/kelly_task/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/task_protocol/kelly_task/__init__.py
@@ -0,0 +1 @@
+
diff --git a/kelly_record_task.py b/task_protocol/kelly_task/kelly_record_task.py
similarity index 93%
rename from kelly_record_task.py
rename to task_protocol/kelly_task/kelly_record_task.py
index 1440cce..a149eb8 100755
--- a/kelly_record_task.py
+++ b/task_protocol/kelly_task/kelly_record_task.py
@@ -15,7 +15,9 @@
)
# all modules above this line will have logging disabled
-# import behavbox_test
+# updated with reorganization (on 7/11/2023)
+import sys
+sys.path.insert(0,'/home/pi/RPi4_behavior_boxes/essential')
import behavbox
class KellyRecordTask(object):
def __init__(self, **kwargs): # name and session_info should be provided as kwargs
diff --git a/kelly_task.py b/task_protocol/kelly_task/kelly_task.py
similarity index 98%
rename from kelly_task.py
rename to task_protocol/kelly_task/kelly_task.py
index 73cae35..f3ce1f1 100755
--- a/kelly_task.py
+++ b/task_protocol/kelly_task/kelly_task.py
@@ -17,7 +17,9 @@
}
)
# all modules above this line will have logging disabled
-
+# updated with reorganization (on 7/11/2023)
+import sys
+sys.path.insert(0,'/home/pi/RPi4_behavior_boxes/essential')
import behavbox
# adding timing capability to the state machine
diff --git a/run_kelly_task.py b/task_protocol/kelly_task/run_kelly_task.py
similarity index 100%
rename from run_kelly_task.py
rename to task_protocol/kelly_task/run_kelly_task.py
diff --git a/run_record_task.py b/task_protocol/kelly_task/run_record_task.py
similarity index 100%
rename from run_record_task.py
rename to task_protocol/kelly_task/run_record_task.py
diff --git a/session_info_year-month-date.py b/task_protocol/kelly_task/session_info_year-month-date.py
similarity index 100%
rename from session_info_year-month-date.py
rename to task_protocol/kelly_task/session_info_year-month-date.py
diff --git a/task_protocol/self_admin_task/__init__.py b/task_protocol/self_admin_task/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/task_protocol/self_admin_task/__init__.py
@@ -0,0 +1 @@
+
diff --git a/remi_self_admin_task.py b/task_protocol/self_admin_task/remi_self_admin_task.py
similarity index 99%
rename from remi_self_admin_task.py
rename to task_protocol/self_admin_task/remi_self_admin_task.py
index 5b28f8e..76db1a1 100644
--- a/remi_self_admin_task.py
+++ b/task_protocol/self_admin_task/remi_self_admin_task.py
@@ -46,7 +46,9 @@
}
)
# all modules above this line will have logging disabled
-
+# updated with reorganization (on 7/11/2023)
+import sys
+sys.path.insert(0,'/home/pi/RPi4_behavior_boxes/essential')
import behavbox
# import ivsa_syringe_pump # I will need to add the ivsa_syringe_pump class to the behavbox code
diff --git a/run_remi_self_admin_task.py b/task_protocol/self_admin_task/run_remi_self_admin_task.py
similarity index 100%
rename from run_remi_self_admin_task.py
rename to task_protocol/self_admin_task/run_remi_self_admin_task.py
diff --git a/run_self_admin_task.py b/task_protocol/self_admin_task/run_self_admin_task.py
similarity index 100%
rename from run_self_admin_task.py
rename to task_protocol/self_admin_task/run_self_admin_task.py
diff --git a/self_admin_task.py b/task_protocol/self_admin_task/self_admin_task.py
similarity index 99%
rename from self_admin_task.py
rename to task_protocol/self_admin_task/self_admin_task.py
index fec7a43..1f04a15 100644
--- a/self_admin_task.py
+++ b/task_protocol/self_admin_task/self_admin_task.py
@@ -36,7 +36,9 @@
}
)
# all modules above this line will have logging disabled
-
+# updated with reorganization (on 7/11/2023)
+import sys
+sys.path.insert(0,'/home/pi/RPi4_behavior_boxes/essential')
import behavbox
diff --git a/session_info_self_admin.py b/task_protocol/self_admin_task/session_info_self_admin.py
similarity index 100%
rename from session_info_self_admin.py
rename to task_protocol/self_admin_task/session_info_self_admin.py
diff --git a/treadmill_20211115.ino b/treadmill_20211115.ino
deleted file mode 100644
index 31e5267..0000000
--- a/treadmill_20211115.ino
+++ /dev/null
@@ -1,145 +0,0 @@
-// when the treadmil encoder is located in the front
-// include rev output for stablity
-//#include
-#include
-#define VERSION "20211112"
-// ===== VERSIONS ======
-#define MAXSPEED 1000.0f // maximum speed for dac out (mm/sec)
-#define MAXDACVOLTS 2.5f // DAC ouput voltage at maximum speed
-#define MAXDACCNTS 4095.0f // maximum dac value
-//float maxDACval = MAXDACVOLTS * MAXDACCNTS / 3.3; // limit dac output to max allowed
-float maxDACval = MAXDACVOLTS * MAXDACCNTS / 3.3 / 2; // limit dac output to max allowed // JR edit 5/28/19 make in both directions
-#define encAPin 0
-#define encBPin 1
-#define dacPin A14
-//#define idxPin 2 // not use d here
-
-// counts per rotation of treadmill encoder wheel
-// 200 counts per rev
-// 1.03" per rev
-// so - 1.03 * 25.4 * pi / 200 /1000 = microns/cnt
-#define MM_PER_COUNT 410950 // actually 1/10^6mm per count since we divide by usecs
-#define DIST_PER_COUNT ((float)MM_PER_COUNT/1000000.0)
-//(float)0.41095
-#define SPEED_TIMEOUT 50000 // if we don't move in this many microseconds assume we are stopped
-static float runSpeed = 0;
-static float lastSpeed = 0;
-volatile uint32_t lastUsecs;
-volatile uint32_t thisUsecs;
-volatile uint32_t encoderUsecs;
-volatile float distance = 0;
-int counts = 0; // net count
-
-int countAdj = 0; // 0-250 and 0-50 for negative 50-250 for positive
-//int rev = 0;//count revolution
-#define FW 1
-#define BW -1
-int dir = FW;
-// ------------------------------------------
-// interrupt routine for ENCODER_A rising edge
-// ---------------------------------------------
-void encoderInt()
-{
- int ENCA = digitalRead(encAPin); // always update output
- int ENCB = digitalRead(encBPin);
- if (ENCA == ENCB ) // figure out the direction
- {
- Serial.print('F');
- dir = FW;
- thisUsecs = micros();
- encoderUsecs = thisUsecs - lastUsecs;
- lastUsecs = thisUsecs;
- runSpeed = (float)MM_PER_COUNT / encoderUsecs;
- distance += DIST_PER_COUNT;
- counts += 1;
- }
- else
- {
- Serial.print('B');
- dir = BW;
- thisUsecs = micros();
- encoderUsecs = thisUsecs - lastUsecs;
- lastUsecs = thisUsecs;
- runSpeed = (float)MM_PER_COUNT / encoderUsecs* -1;
- distance -= DIST_PER_COUNT;
- counts -= 1;
- }
-}
-void setup()
-{
- //Serial.begin(115200);
- //Serial2.begin(115200);
- Serial.begin(19200);
- Serial2.begin(19200);
- //while ( !Serial); // if no serial USB is connected, may need to comment this out
- pinMode(encAPin, INPUT_PULLUP); // sets the digital pin as input
- pinMode(encBPin, INPUT_PULLUP); // sets the digital pin as input
- analogWriteResolution(12);
-
- Serial.print("Treadmill Interface V: ");
- Serial.println(VERSION);
- Serial.println("distance,speed");
- Serial.println(maxDACval);
-
- Wire.begin(8);
- Wire.setSDA(18);
- Wire.setSCL(19);
- Wire.onRequest(sendData);
-
- lastUsecs = micros();
- attachInterrupt(encAPin, encoderInt, RISING); // check encoder every A pin rising edge
-}
-void loop()
-{
- noInterrupts();
- uint32_t now = micros();
- uint32_t lastU = lastUsecs;
- if ( (now > lastU) && ((now - lastU) > SPEED_TIMEOUT) )
- { // now should never be < lastUsecs, but sometiems it is
- // I question if noInterupts works
- runSpeed = 0;
- }
- interrupts();
- if ( runSpeed != lastSpeed )
- {
- lastSpeed = runSpeed;
- // float dacval = runSpeed / MAXSPEED * maxDACval;
- float dacval = (.5 + runSpeed / MAXSPEED) * maxDACval;
- if ( dacval < 0 ) dacval = 0;
- if ( dacval > maxDACval) dacval = maxDACval;
-// Serial.print(distance);
- countAdj = counts+50;
- if (countAdj>250)
- {
- counts=1;
- countAdj = 51;
- }
- if (counts<-50){
- counts = -50;
- countAdj = 0;
- }
- Serial.print(countAdj);
- Serial.print(",");
- Serial.println(runSpeed);
- int a=(uint16_t)dacval-730;
- analogWrite(A14, (uint16_t) dacval);
- Serial.println("iiiiiiiiiiiiiii");
- Serial.println(a);
-// Wire.onRequest(sendData); //for debug purpose
-// Wire.write(counts); //for transmitting the count as data
- Serial2.write(counts);//Serial2.write(a);
- }
-// Serial.println(distance);d
-}
-
-void sendData()
-{
-// long Dst = distance;
-// long Spd = runSpeed;
-// long data = (Dst << 8) | Spd;
-// Wire.write(data);
-// Serial.println(data);
- Wire.write(counts); //for transmitting the count as data
-// Wire.write("iiiiiiiiiiiiiii");
-// Wire.write(a);
-}
\ No newline at end of file