
#============================================== About Copyright ======================================================
# Copyright (c) 2026 Shintaro Otsuka
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#============================================== Developer Note =======================================================
# Resolution of both monitor are 1366x768 pixels.
# How to add task?: Add button/initialize/AutoTaskSwitchPhase/Task itself
# To do: Check auto task switch,divide large movie, LED manual control in housing analysis, Ignore 1 frame nosepoke function, Take measures for USB-monitor disconnection
# To do at the 1st run: Upload "SerialConnectionWithPython7.ino" into arduino, Set path, Set panel positions
# Note: Users have to init their local variables which should be reset between sessions by themselves (Ideally within init of phase2)
# Panel ID start from 1 while ROI ID start from 0 (To congruent the panel and roi ID)

# Plug-in which should be installed: OpenCV
# Tips of python: global variable can be read from function without statement, but cannot assign (Caution: Mistaking local variable for global variable can be easily happened)
#m*: label, i*:iEntry, b*:button
#RoiID: Roi0-water slit, Roi1-panel 0, Roi2-panel 1...
# Mail server account is same as google account
# PanelROI background is updated every 20 frames and kept 5 time points.
# Max task num:100 Max Roi Num:40
#============================================== General Setting ======================================================
RaspberryMode = 1   # 0:PC mode, 1:Raspberry mode
SingleMonitorMode = 1   # If 1, the windows arranged for single monitor operation
IsHousingAnalysis = 1 # If housing analysis is working, the value = 1, otherwise = 0
TouchDetectSensorType = 0  # 0:Detect with camera  1:Detect with mouse cursor(for PC & airbar)

TouchMonitorWidth = 1280        #1366   #1280
TouchMonitorHeight = 800        #768    #800
OperationMonitorWidht = 1280    #1366   #1280
OperationMonitorHeight = 800    #768    #800


if RaspberryMode==0:
    PortName='COM3'    # You can check this port name through device manager
if RaspberryMode==1:
    PortName="/dev/ttyACM0"

CameraID=0  # This value is used for starting recording with opencv (If there is only 1 camera, assign 0. If miniscope is connected, assign 1)
CameraWindowScaleX=2  # Change camera window size here (exp. if you want to make the camera window size half, enter 2)
CameraWindowScaleY=2
BlinkFreq = 100000 # Frequency of LED blink can be changed here (default: 100000)

CamExposureFix = 1  # 0:auto-exposure mode, 1:fix mode
CamExposureFixMode = 0  # 0: without using subprocess, 1: use subprocess(Hashizume sensei); If your camera doesn't work at raspberry pi, try both "0" and "1".
#========General setting2====================================================================================
WinApiForCamera=0   # Window API for camera capturing (0:DSHOW, 1:MSMF)
MaxTaskNum = 100  # Max number of tasks
MaxPanelNum = 20
MaxRoiNum = 20
DigitalOutChNum=14  # Ch num of Arduino digital output
ServoChNum=14
if RaspberryMode==0:    # Windows mode (If this program is run by windows)
    ULXofTouchWindow = OperationMonitorWidht  # Left-up position of the touch panel window
    if TouchDetectSensorType == 0:   # Camera detect mode
        if SingleMonitorMode == 1:  # Single monitor mode
            ULYofTouchWindow = 300  # 25  #300
        if SingleMonitorMode == 0:  # Double monitor mode
            ULYofTouchWindow = 0
    if TouchDetectSensorType == 1:  # Airbar detect mode
        ULYofTouchWindow = 0

if RaspberryMode==1:    # Raspi mode(If this program is run by Raspberry pi 4)
    if SingleMonitorMode==1:  # Single monitor mode
        ULXofTouchWindow = 0  # Left-up position of the touch panel window
        ULYofTouchWindow = 300  #25  #300
    if SingleMonitorMode == 0:  # Double monitor mode
        ULXofTouchWindow = OperationMonitorWidht  # Left-up position of the touch panel window
        ULYofTouchWindow = 0

TouchWindowWidth = TouchMonitorWidth    #1366
TouchWindowHeight = TouchMonitorHeight  #850
if RaspberryMode == 0:    # Windows mode
    MainWindowULX = 100
    MainWindowULY = 0
if RaspberryMode == 1:    # Raspi mode
    MainWindowULX = 0
    MainWindowULY = 20

MainWindowWidth = 1220  #1300
MainWindowHeight = 220
MainWindowLeftFrameWidth = 1300  #1230 1300
MainWindowLeftFrameHeight = 500


if RaspberryMode == 0:
    ServoWindowPosX=100    #280 240 270
    ServoWindowPosY=300
    DOutWindowPosX=100
    DOutWindowPosY=510
if RaspberryMode == 1:
    ServoWindowPosX=MainWindowULX    #280 240 270
    ServoWindowPosY=MainWindowULY+MainWindowHeight+30
    DOutWindowPosX=MainWindowULX
    DOutWindowPosY=MainWindowULY+MainWindowHeight+270   #510

#ServoWindowWidth = 600
#ServoWindowHeight = 480
DOutWindowWidth=300
DOutWindowHeight=480

if RaspberryMode==0:
    CameraWindowPosX=240    #280 240 270
    CameraWindowPosY=300    #300
if RaspberryMode==1:
    CameraWindowPosX=170    #280 240 270
    CameraWindowPosY=MainWindowULY+MainWindowHeight+60  #300

RoiWindowPosX = 940
RoiWindowPosY = MainWindowULY+MainWindowHeight+30
RoiWindowWidth = 10
RoiWindowHeight = 10
RoiEntryWidth=4 # Entry x size of ROI thresholds

MovieWidth = 320
MovieHeight = 240
CharaMesX = 100
CharaMesY = 0

MainWindowCenterFrameX = 100 # The X coordinate of upper left position of the GUI frame which shows task phase control button
MainWindowCenterFrameY = 30
MainWindowCenterFrameWidth=100
MainWindowCenterFrameHeight=160

MainWindowRightFrameX = 100 # The X coordinate of upper left position of the GUI frame which shows task buttons
MainWindowRightFrameY = 30
MainWindowRightFrameWidth=1377#1230
MainWindowRightFrameHeight=160#150

RoiDensity=0.0 # Sampling density of nosepoke detection (pixel) 10 20
SamplingDotSize=1
RecordFps=10     # Recording FPS
PlayBackFps=30  # Playback speed of captured movie (not in use)
TargetFps=30 # FPS of this software (main loop)
#===========================================================================================================

import cv2  # For camera capturing
import numpy as np
import datetime  # For getting time
import time
import os  # For the checking of folder/file
import pickle  # Module for saving parameters
import smtplib  # For sending notification email
if RaspberryMode == 0:
    import win32api  # For get mice cursor coordinates in the desktop
import random
from email.mime.text import MIMEText
from email.utils import formatdate
from tkinter import *  # For GUI
from tkinter import filedialog
from tkinter import ttk
from tkinter import messagebox
#import tkinter.filedialog, tkinter.messagebox
import serial  # Module for the operation of arduino
import math
import functools
if CamExposureFixMode==1:
    import subprocess

Phase = 0 # Current main phase  -99:Setting, -100:Setting2
Phase2 = 0
Phase3 = 0  # Used only in live imitation task
PanelSetPhase=0
Task = 0 # Number of current task
Path=''
IsLightPhase=1  # This value is 1 during light phase
IsTouchWindowOn=0 # If 1, touch window is shown
TouchWindowToggle=1 # 1:turn on touchwindow, -1:turn off touchwindow

MxDesk=-1   # Mice coordinate in the desktop
MyDesk=-1
MxCam = -1   # Mice cursor coordinate in the camera window
MyCam = -1
PreMxCam = -1   # Mice cursor coordinate of the previous frame in the camera window
PreMyCam = -1
MxTk = -1  # Mice cursor coordinate in the touch panel window
MyTk = -1
PreMxTk = -1  # Mice cursor coordinate of the previous frame in the touch panel window
PreMyTk = -1
TouchX=-1   # Actual touched position on the monitor
TouchY=-1
PreTouchX=-1   # Actual touched position on the monitor
PreTouchY=-1
CrossFireX = 100
CrossFireY = 100
CrossFireMoveDistance = 10.0  # Move distance by one button click
PanelUsed = [[0 for i in range(MaxPanelNum)] for j in range(MaxTaskNum)]     # Whether each panel is used or not
PanelULX = [[0 for i in range(MaxPanelNum)] for j in range(MaxTaskNum)]
PanelULY = [[0 for i in range(MaxPanelNum)] for j in range(MaxTaskNum)]
PanelBRX = [[0 for i in range(MaxPanelNum)] for j in range(MaxTaskNum)]
PanelBRY = [[0 for i in range(MaxPanelNum)] for j in range(MaxTaskNum)]
Init=0

CameraResolutionX = 0 #640
CameraResolutionY = 0#480
CapturedImgWidth = 0
CapturedImgHeight = 0

ServoGuiEnabled=[0]*ServoChNum
ServoGuiLabeled=0   # If 1, labels were put on the servo gui window

mDigitalOut=[0]*DigitalOutChNum
DigitalOutEnabled=[0]*14
DigitalOutGuiUpdateTrg=0

ShowRoi = 0 # Switch to show or hide ROIs

RoiUsed = [[0 for i in range(MaxRoiNum)] for j in range(MaxTaskNum)]
for i in range(MaxTaskNum):
    RoiUsed[i][19]=1 # Activate water slit nosepoke ROI
Roi1X = [[0 for i in range(MaxRoiNum)] for j in range(MaxTaskNum)]
Roi1Y = [[0 for i in range(MaxRoiNum)] for j in range(MaxTaskNum)]
Roi2X = [[0 for i in range(MaxRoiNum)] for j in range(MaxTaskNum)]
Roi2Y = [[0 for i in range(MaxRoiNum)] for j in range(MaxTaskNum)]

RoiDetect = [[0 for i in range(MaxRoiNum)] for j in range(MaxTaskNum)]
RoiPreDetect = [[0 for i in range(MaxRoiNum)] for j in range(MaxTaskNum)]
RoiHitNum = [[0 for i in range(MaxRoiNum)] for j in range(MaxTaskNum)]
HighestInt=0
IntArray = [0 for i in range(3000)]
PreRoiIntArray = [[0 for i in range(3000)] for j in range(MaxRoiNum)]  # Used to keep intensities of ROIs in the previous frame
RoiIntLogLight = [[[0 for i in range(5)] for i in range(3000)] for j in range(MaxRoiNum)]  # Used to keep intensities of ROIs in the previous frame
RoiIntLogDark = [[[0 for i in range(5)] for i in range(3000)] for j in range(MaxRoiNum)]  # Used to keep intensities of ROIs in the previous frame
RoiInitDark = [0 for i in range(MaxRoiNum)] #If 1, the init of the Roi in dark condition has done
RoiInitLight = [0 for i in range(MaxRoiNum)]

RoiProperty = [[0 for i in range(3)] for j in range(MaxRoiNum)] # P1(Detection type) = 0:Just use light intensity th. 1:Use 5sec intensity history for background. 2:Just use light intensity th and yellow object is ignored.  P2(Direction of Th) = 0:White background. 1:Black background. P3(Showing detection symbol)=1: Show detection symbol
RoiDetectNum=0   # Number of ROIs activated simltaneously
RoiGuiLabeled=0*MaxRoiNum   # If 1, labels were put on the ROI GUI window
LeverPressNum=0 # Number of levers pressed simltaneously
for i in range(MaxRoiNum):  # Set default values
    if i==19:
        RoiProperty[i][0] = 0   # Mode 0 and detect dark object
        RoiProperty[i][1] = 0
        RoiProperty[i][2] = 1
    if i != 19:
        RoiProperty[i][0] = 1   # Mode 1 and detect bright object
        RoiProperty[i][1] = 1
        RoiProperty[i][2] = 0
RoiSamplingNum=[0]*MaxRoiNum
StepX=[0.0]*MaxRoiNum
StepY=[0.0]*MaxRoiNum
ManualRoiDetectionID = -1
ManualRoiDetectionCnt = 0

TouchPanelRef = [0]*MaxPanelNum
ManualPanelRef = [0]*MaxPanelNum    # For test
ManualBlinkPanelRef = [0]*MaxPanelNum   # For test
IsHiddenPanel = [0]*MaxPanelNum   # If 1, a correspondent panel blinks
TypeOfPanel = [0]*MaxPanelNum   # 0:Normal 1:Blinking 2:Textured
BlinkPanelNum=0  # 1 means there is more than 1 panel blinkings
OHCnt=0 # Total frame of operant house update
EndFlag = 0   # If 1, program will be quitted
TaskEndFlag = 0
PanelFrameCnt =[0]*MaxPanelNum  # The number of frames after each panel turned on

SaveTrg = 0
ManualPanelOnTrg=0  # If 1, manual panels are activated
ManualBlinkPanelOnTrg=0  # If 1, manual blink panels are activated
ManualBlinkPanelOn=0  # If 1, manual blink panels are shown
PickleInst = [0] * MaxTaskNum
TouchDetectionOnCnt=0 # If any mouse cursor is detected, the value > 0
TouchSymbolCnt = 0
# Nosepoke ROI
NosePokeRoiWidth=0  # Width of nosepoke ROI
NosePokeRoiHeight=0
Position = [[0 for i in range(2)] for j in range(2)]
DuringCameraReset=0 # If 1, camera is during reset (Camera capture is not executed during reset)
#CamResetDay=-1
#CamResetHour=12
#CamResetMinute=48
DebugWithoutArduinoMode=0   # If 1, serial connection is not working
AutoTaskSwitchPhase=0    # If 1, next task switch sequence is started automatically when phase backs to 0.
NextTaskID=0
PanelChanged=0  # If panel is turned on or off, 1

Distance=0
RoiMovePhase=0
GrabbedID=-1
GrabbedRoiVertex=-1
NowPunishing = 0
NosePokeTh=50
PointedPixelInt=0    # Total light intensity of pointed pixel

CamExposureLight=0
CamExposureDark=0

LightPhaseOnsetHour=-1
LightPhaseOnsetMinute=-1
DarkPhaseOnsetHour=-1
DarkPhaseOnsetMinute=-1

ExperimentStartYear = 0
ExperimentStartMonth = 0
ExperimentStartDay = 0
ExperimentStartHour = 0
ExperimentStartMinute = 0
ExperimentStartSecond = 0.0
TaskStartedYear = 0
TaskStartedMonth = 0
TaskStartedDay = 0
TaskStartedHour = 0
TaskStartedMinute = 0
TaskStartedSecond = 0.0

TaskStartHour = [-1] * 4    # Time (hour) of starting of task in housing analysis
TaskStartMinute = [-1] * 4   # Time (minute) of starting of task in housing analysis

TimerRunning=[0]*8  # 0-3:For tasks, 4: , 5:For task time limit, 6:For temporal suspension of nosepoke detection    7:For camera reset
TimerNowTime=[0.0]*8
TimerPreTime=[0.0]*8
TimerCounter=[0]*8
TimerSec=[0.0]*8
ServoWorkTime=1.0   # Duration of power on of the servo

# Variables for arbitary water supply(AWS)
AWS_On=0    # If 1, AWS works
AWS_IndicatedDur=0  # Required nosepoke duration
AWS_Dur=0   # Nosepoke duration during AWS
AWS_PreFrameMilliSec=0  # Time of pre frame in millisec
AWS_CurrFrameMilliSec=0 # Time of current frame in millisec
AWS_Stat=0  # 1 means AWS is completed
ButtonAWS_On=0 # If 1, button activated AWS is working

FpsSec = 0
FpsPreSec = 0
ButtonRef = [0]*100
ButtonRef[1] = 2
FrameNum = 0
FPS = 0.0
FrameNumPerSec = 0
CurrentPanelNum = 0
TimeNow = datetime.datetime.now()
IsThereEndTaskNowButton=0

IndicatedServoPos=0     # Indicate position of water nozzle, 0:intermediate, 1:inside, 2:outside, -1:power off the servo(for silencing)
IndicatedDigitalOut = [0]*14 # If this value is 1, channel 1 of digital output of arduino uno is turned on. If -1, turn off. If 0, do nothing.
DigitalOut=[0]*14
OutInt=[0]*16              # Output values to arduino through serial connection
DigitalOutBlinkActive=[0]*14    # If 1, the channel output intermittently
ServoAngle=[-1]*14  # If -1, the servo channel is not in use
IndicatedDigitalIn = [0]*14  # If 1, digital input mode will be activated
DigitalIn = [0]*14

InputFromArduinoEnabled=0    # If 1, python read input from arduino
AnalogInputBytes=b'a'
InputText=""
InputArray=[""]*2

ServoPos=0
LightCycleControl = 0 # If 1, ceiling illumination turn on and off based on designated time window
if IsHousingAnalysis==1:
    LightCycleControl=1
ManualRoofLightCnt=0  # This counter is used for temporal inactivation of light cycle control

NowRecording=0  # During recording, this value is 1
EndRecordTimerOn=0  # If 1, end record timer is functional
EndRecordTimerCnt=0 # When this counter equals 0, the recording is stopped
NosePokeDetectionOn=1  #If 1, nose poke detection is functional
NowLickRecording=0  #
StartLickRecordingTrg=0 # If 1, recording of lick starts
EndLickRecordingTrg=0   # If 1, recording of lick ends

SendingTtl=0                # If 1, TTL output is started
TtlPower=0                  # If 1, TTL signal is sent

TtlITV=2000                 #Frequency of TTL pulse (msec)
Ttl1stSquareDuration=1200   #Width of 1st TTL square pulse(msec)
TtlSquareDuration=1000      #Width of the following TTL square pulse(msec)
ElapsedTime=0               #Elapsed time after starting ttl pulse output (msec)
ElapsedTimePerFrame=0       #Elapsed time in the current frame(msec)
TtlPreTime=0                #in ms, For caluculation
TtlCurrTime=0               #in ms, For caluculation
TtlPreQuotient=0            #For caluculation
TtlCurrQuotient=0           #For caluculation
TtlCurrRemainder = 0        #For caluculation
TtlSquareElapsedTime=0      #For caluculation
TtlIsFirst=1                #This value is 1 until 1st long-wide pulse is output

NextShatterTime=0.0
CaptureNum=0

CurrentChannelID=0
Angle=1    # Angle of servo
TempAngle=0

ServoOutputBook=0   # If 1, angle of the servo in the arduino is updated through serial connection
DigitalPinOutputBook=0     # If 1, status of digital output pin in the arduino is updated through serial connection

MouseInput=0

TouchX_Scale=0.0
TouchX_Shift=0
TouchY_Scale=0.0
TouchY_Shift=0

if SingleMonitorMode == 1:
    IsCameraWinEnlarged = -1
if SingleMonitorMode == 0:
    IsCameraWinEnlarged = 1

TouchCursorON = 1 # If 1, orange touch cursor is shown
BCC = 'receiver2@test.net'
bStartNow=None # Prepare for the reference of button
bTimePlus=None
bTimeMinus=None
bBackToPara=None
bEndTaskNow=None
BackButtonTrg=0 # 1 is assigned when "Back" button is clicked
EndTaskNowButtonTrg=0  # 1 is assigned when "EndNow" button is clicked


DispVariable=[['' for i in range(2)] for j in range(10)] # Use can show variables of their task through this variable

try:
    ser = serial.Serial(PortName, 115200,timeout=0) # Connect to arduino
    print('Arduino is detected.')
except serial.serialutil.SerialException:   # If arduino is not found
    DebugWithoutArduinoMode=1   # Run as non-arduino mode
    print('Arduino is not detected.')

# Make Touch window
TouchWindowRoot = Tk()
TouchWindowRoot.title("Touch panel")
TouchWindowRoot.geometry(str(TouchWindowWidth)+"x"+str(TouchWindowHeight))    # Create Touch window
TouchWindowRoot.geometry('+'+str(ULXofTouchWindow)+'+'+str(ULYofTouchWindow))    # Move window
TouchWindowRoot.resizable(0,0) # Prohibit the resize of touch window
TouchWindowRoot.overrideredirect(1)
CanvasTouchWindow = Canvas(TouchWindowRoot, width = TouchWindowWidth, height = TouchWindowHeight)

CanvasTouchWindow.create_rectangle(0, 0, TouchWindowWidth+1, TouchWindowHeight+1, fill = 'black')  # Draw dark background
CanvasTouchWindow.place(x=-2, y=-2)

# Make main window
MainWindowRoot = Tk()
MainWindowRoot.title("Main")
MainWindowRoot.geometry("+"+str(MainWindowULX)+"+"+str(MainWindowULY))   #"+100+5"
MainWindowRoot.geometry(str(MainWindowWidth)+"x"+str(MainWindowHeight)) #"1230x220"
MainWindowLeftFrame = ttk.Frame(MainWindowRoot, width=MainWindowLeftFrameWidth, height=MainWindowLeftFrameHeight, relief='flat', borderwidth=5)
MainWindowLeftFrame.place(x=0, y=0)
MainWindowCenterFrame = ttk.Frame(MainWindowRoot, width=MainWindowCenterFrameWidth, height=MainWindowCenterFrameHeight, relief='flat', borderwidth=5) #
MainWindowCenterFrame.place(x=MainWindowCenterFrameX, y=MainWindowCenterFrameY)
MainWindowRightFrame = ttk.Frame(MainWindowRoot, width=MainWindowRightFrameWidth, height=MainWindowRightFrameHeight, relief='flat', borderwidth=5)
MainWindowRightFrame.place(x=MainWindowRightFrameX, y=MainWindowRightFrameY, width=MainWindowRightFrameWidth, height=MainWindowRightFrameHeight) #

RecipientAddressVar = StringVar(MainWindowRoot) # e-mail for the receiving task finish notification
SenderAddressVar = StringVar(MainWindowRoot)
SenderPasswordVar = StringVar(MainWindowRoot)
SmtpServerVar = StringVar(MainWindowRoot)
SmtpPortVar = StringVar(MainWindowRoot)
SecurityTypeVar = StringVar(MainWindowRoot)
TouchX_ShiftVar = StringVar(MainWindowRoot) #
TouchY_ShiftVar = StringVar(MainWindowRoot) #
TouchX_ScaleVar = StringVar(MainWindowRoot) #
TouchY_ScaleVar = StringVar(MainWindowRoot) #
DeviceNameVar=StringVar(MainWindowRoot) #
ArduinoConnectionVar=StringVar(MainWindowRoot) #
MouseDebugModeVar=StringVar(MainWindowRoot) # If ON, mouse cursor = touched position
CameraCaptureFreqVar=StringVar(MainWindowRoot) # Capturing freqency of camera (Use larger number than 1 only when camera capturing somehow takes very long time).
CableDetectCorrValueVar=StringVar(MainWindowRoot)   # Correction value for the detection of cable color (For avoiding to detect cable as nose poke, Higher value increase detect sensitivity)
TaskStartTime1Var=StringVar(MainWindowRoot) # Time(exp:23:00) when task is started (For housing analysis)
TaskStartTime2Var=StringVar(MainWindowRoot)
TaskStartTime3Var=StringVar(MainWindowRoot)
TaskStartTime4Var=StringVar(MainWindowRoot)
TouchOffTimeVar=StringVar(MainWindowRoot)   # Sampling density of nosepoke detection (pixel)
RoiDensityVar=StringVar(MainWindowRoot)

LightPhaseOnsetTimeVar=StringVar(MainWindowRoot)
DarkPhaseOnsetTimeVar=StringVar(MainWindowRoot)

MovieWidthVar=StringVar(MainWindowRoot)
MovieHeightVar=StringVar(MainWindowRoot)
RecordFpsVar=StringVar(MainWindowRoot)
PlayBackFpsVar=StringVar(MainWindowRoot)

CamExposureLightVar=StringVar(MainWindowRoot)
CamExposureDarkVar=StringVar(MainWindowRoot)

CopyRoiFromVar=StringVar(MainWindowRoot)
CopyRoiTo1Var=StringVar(MainWindowRoot)
CopyRoiTo2Var=StringVar(MainWindowRoot)
CopyRoiTo3Var=StringVar(MainWindowRoot)
CopyRoiTo4Var=StringVar(MainWindowRoot)
CopyRoiTo5Var=StringVar(MainWindowRoot)

#Str='aaa'
PanelTexturePath = ['']*4   # Texture path of panel
#PanelTexturePath = [['' for i in range(4)] for j in range(4)]
# Make control window
ServoWindowRoot = Tk()
ServoWindowRoot.title("Servo")
#ServoWindowRoot.geometry(str(ServoWindowWidth)+'x'+str(ServoWindowHeight))
ServoWindowRoot.geometry('+'+str(ServoWindowPosX)+'+'+str(ServoWindowPosY))  #100,300  '+100+300'
ServoWindowFrame1 = ttk.Frame(ServoWindowRoot, width=300, height=480, relief='flat', borderwidth=5)
ServoWindowFrame1.grid(row=0, column=0, sticky=(N, E, S, W))   # Make frame?
ServoWindowFrame2 = ttk.Frame(ServoWindowRoot, width=300, height=300, relief='flat', borderwidth=5)
ServoWindowFrame2.grid(row=1, column=0, sticky=(N, E, S, W))   # Make frame?
#ServoWindowRoot.geometry('+100+1400')  #100,300  '+100+300'

InAngleVar = [""]*ServoChNum
InAngle = [0]*ServoChNum
MidAngleVar = [""]*ServoChNum
MidAngle = [0]*ServoChNum
OutAngleVar = [""]*ServoChNum
OutAngle = [0]*ServoChNum
for i in range(ServoChNum):
    InAngleVar[i] = StringVar(ServoWindowRoot)
    MidAngleVar[i] = StringVar(ServoWindowRoot)
    OutAngleVar[i] = StringVar(ServoWindowRoot)

# Make digital out window
DOutWindowRoot = Tk()
DOutWindowRoot.title("DigitalOut")
DOutWindowRoot.geometry('+'+str(DOutWindowPosX)+'+'+str(DOutWindowPosY))  #100,300  '+100+300'
DOutWindowFrame = ttk.Frame(DOutWindowRoot, width=DOutWindowWidth, height=DOutWindowHeight, relief='flat', borderwidth=5)
DOutWindowFrame.grid(row=0, column=0, sticky=(N, E, S, W))   # Make frame?


RoiWindowRoot = Tk()
RoiWindowRoot.title("ROI Th")
RoiWindowRoot.geometry('+'+str(RoiWindowPosX)+'+'+str(RoiWindowPosY))
RoiWindowFrame = ttk.Frame(RoiWindowRoot, width=RoiWindowWidth, height=RoiWindowHeight, relief='flat', borderwidth=5)
RoiWindowFrame.grid(row=0, column=0, sticky=(N, E, S, W))   # Make frame?
LightThList = [[0 for i in range(MaxRoiNum)] for j in range(MaxTaskNum)]
LightThListVar = [["0" for i in range(MaxRoiNum)] for j in range(MaxTaskNum)]
for i in range(MaxTaskNum):
    for i2 in range(MaxRoiNum):
        LightThListVar[i][i2] = StringVar(RoiWindowRoot)

DarkThList = [[0 for i in range(MaxRoiNum)] for j in range(MaxTaskNum)]
DarkThListVar = [["0" for i in range(MaxRoiNum)] for j in range(MaxTaskNum)]
for i in range(MaxTaskNum):  #
    for i2 in range(MaxRoiNum):
        DarkThListVar[i][i2] = StringVar(RoiWindowRoot)

NumThList = [[0 for i in range(MaxRoiNum)] for j in range(MaxTaskNum)]
NumThListVar = [["0" for i in range(MaxRoiNum)] for j in range(MaxTaskNum)]
for i in range(MaxTaskNum):
    for i2 in range(MaxRoiNum):
        NumThListVar[i][i2] = StringVar(RoiWindowRoot)

#StripesPng = [PhotoImage(file="TextureTemplate2.png"),  PhotoImage(file="TextureTemplate2.png")]
PanelTextureImage = [PhotoImage(file="TextureTemplate.png"),  PhotoImage(file="TextureTemplate.png")]

class mouseParam:   # Class for get input information of mouse (in the Open CV window)
    def __init__(self, input_img_name):
        self.mouseEvent = {"x": None, "y": None, "event": None, "flags": None}  # Parameters for input of mouse
        cv2.setMouseCallback(input_img_name, self.__CallBackFunc, None) # Setting of mouse input
    def __CallBackFunc(self, eventType, x, y, flags, userdata): # Call back
        self.mouseEvent["x"] = x
        self.mouseEvent["y"] = y
        self.mouseEvent["event"] = eventType
        self.mouseEvent["flags"] = flags
    def getData(self):  # Function for returning parameters for mouse input
        return self.mouseEvent
    def getEvent(self): # Function for returning mice eventマウスイベントを返す関数
        return self.mouseEvent["event"]
    def getFlags(self): # Function for returning flag of mosue
        return self.mouseEvent["flags"]
    def getX(self): # Returning x coordinate
        return self.mouseEvent["x"]
    def getY(self): # Returning y coordinate
        return self.mouseEvent["y"]
    def getPos(self):   # Returning x and y coordinates
        return (self.mouseEvent["x"], self.mouseEvent["y"])

def SaveGeneralParameter(): #
    global Path, PanelULX, PanelULY, PanelBRX, PanelBRY, MaxRoiNum,  LightThList
    with open('data/Path.dat', 'wb') as fp:
        pickle.dump(Path, fp)

    for i in range(ServoChNum):
        InAngle[i]=int(InAngleVar[i].get())
    with open('data/InAngle.dat', 'wb') as fp:
        pickle.dump(InAngle, fp)
    for i in range(ServoChNum):
        MidAngle[i]=int(MidAngleVar[i].get())
    with open('data/MidAngle.dat', 'wb') as fp:
        pickle.dump(MidAngle, fp)
    for i in range(ServoChNum):
        OutAngle[i]=int(OutAngleVar[i].get())
    with open('data/OutAngle.dat', 'wb') as fp:
        pickle.dump(OutAngle, fp)
    with open('data/TouchX_Shift.dat', 'wb') as fp:
        pickle.dump(TouchX_ShiftVar.get(), fp)
    with open('data/TouchY_Shift.dat', 'wb') as fp:
        pickle.dump(TouchY_ShiftVar.get(), fp)
    with open('data/TouchX_Scale.dat', 'wb') as fp:
        pickle.dump(TouchX_ScaleVar.get(), fp)
    with open('data/TouchY_Scale.dat', 'wb') as fp:
        pickle.dump(TouchY_ScaleVar.get(), fp)
    with open('data/ButtonAWS_DurVar.dat', 'wb') as fp:
        pickle.dump(ButtonAWS_DurVar.get(), fp)
    with open('data/PanelUsed.dat', 'wb') as fp:
        pickle.dump(PanelUsed, fp)
    with open('data/PanelULX.dat', 'wb') as fp:
        pickle.dump(PanelULX, fp)
    with open('data/PanelULY.dat', 'wb') as fp:
        pickle.dump(PanelULY, fp)
    with open('data/PanelBRX.dat', 'wb') as fp:
        pickle.dump(PanelBRX, fp)
    with open('data/PanelBRY.dat', 'wb') as fp:
        pickle.dump(PanelBRY, fp)
    with open('data/RoiUsed.dat', 'wb') as fp:
        pickle.dump(RoiUsed, fp)
    with open('data/Roi1X.dat', 'wb') as fp:
        pickle.dump(Roi1X, fp)
    with open('data/Roi1Y.dat', 'wb') as fp:
        pickle.dump(Roi1Y, fp)
    with open('data/Roi2X.dat', 'wb') as fp:
        pickle.dump(Roi2X, fp)
    with open('data/Roi2Y.dat', 'wb') as fp:
        pickle.dump(Roi2Y, fp)

    for i in range(MaxTaskNum):
        for i2 in range(MaxRoiNum):
            LightThList[i][i2]=int(LightThListVar[i][i2].get())
    with open('data/LightThList.dat', 'wb') as fp:
        pickle.dump(LightThList, fp)

    for i in range(MaxTaskNum):
        for i2 in range(MaxRoiNum):
            DarkThList[i][i2]=int(DarkThListVar[i][i2].get())
    with open('data/DarkThList.dat', 'wb') as fp:
        pickle.dump(DarkThList, fp)

    for i in range(MaxTaskNum):
        for i2 in range(MaxRoiNum):
            NumThList[i][i2]=int(NumThListVar[i][i2].get())
    with open('data/NumThList.dat', 'wb') as fp:
        pickle.dump(NumThList, fp)

    with open('data/RecipientAddress.dat', 'wb') as fp:
        pickle.dump(RecipientAddressVar.get(), fp)
    with open('data/SenderAddress.dat', 'wb') as fp:
        pickle.dump(SenderAddressVar.get(), fp)
    with open('data/SenderPassword.dat', 'wb') as fp:
        pickle.dump(SenderPasswordVar.get(), fp)
    with open('data/SmtpServer.dat', 'wb') as fp:
        pickle.dump(SmtpServerVar.get(), fp)
    with open('data/SmtpPort.dat', 'wb') as fp:
        pickle.dump(SmtpPortVar.get(), fp)
    with open('data/SecurityType.dat', 'wb') as fp:
        pickle.dump(SecurityTypeVar.get(), fp)
    with open('data/DeviceName.dat', 'wb') as fp:
        pickle.dump(DeviceNameVar.get(), fp)
    with open('data/ArduinoConnection.dat', 'wb') as fp:
        pickle.dump(ArduinoConnectionVar.get(), fp)
    with open('data/MouseDebugMode.dat', 'wb') as fp:
        pickle.dump(MouseDebugModeVar.get(), fp)
    with open('data/CameraCaptureFreq.dat', 'wb') as fp:
        pickle.dump(CameraCaptureFreqVar.get(), fp)
    with open('data/PanelTexturePath.dat', 'wb') as fp:
        pickle.dump(PanelTexturePath, fp)
    with open('data/TaskStartTime1.dat', 'wb') as fp:
        pickle.dump(TaskStartTime1Var.get(), fp)
    with open('data/TaskStartTime2.dat', 'wb') as fp:
        pickle.dump(TaskStartTime2Var.get(), fp)
    with open('data/TaskStartTime3.dat', 'wb') as fp:
        pickle.dump(TaskStartTime3Var.get(), fp)
    with open('data/TaskStartTime4.dat', 'wb') as fp:
        pickle.dump(TaskStartTime4Var.get(), fp)
    with open('data/LightPhaseOnsetTime.dat', 'wb') as fp:
        pickle.dump(LightPhaseOnsetTimeVar.get(), fp)
    with open('data/DarkPhaseOnsetTime.dat', 'wb') as fp:
        pickle.dump(DarkPhaseOnsetTimeVar.get(), fp)
    with open('data/MovieWidth.dat', 'wb') as fp:
        pickle.dump(MovieWidthVar.get(), fp)
    with open('data/MovieHeight.dat', 'wb') as fp:
        pickle.dump(MovieHeightVar.get(), fp)
    with open('data/RecordFps.dat', 'wb') as fp:
        pickle.dump(RecordFpsVar.get(), fp)
    with open('data/CamExposureLight.dat', 'wb') as fp:
        pickle.dump(CamExposureLightVar.get(), fp)
    with open('data/CamExposureDakr.dat', 'wb') as fp:
        pickle.dump(CamExposureDarkVar.get(), fp)
    with open('data/PlayBackFps.dat', 'wb') as fp:
        pickle.dump(PlayBackFpsVar.get(), fp)
    with open('data/CableDetectCorrValue.dat', 'wb') as fp:
        pickle.dump(CableDetectCorrValueVar.get(), fp)
    with open('data/RoiDensity.dat', 'wb') as fp:
        pickle.dump(RoiDensityVar.get(), fp)
    with open('data/TouchOffTime.dat', 'wb') as fp:
        pickle.dump(TouchOffTimeVar.get(), fp)

    with open('data/CopyRoiFrom.dat', 'wb') as fp:
        pickle.dump(CopyRoiFromVar.get(), fp)
    with open('data/CopyRoiTo1.dat', 'wb') as fp:
        pickle.dump(CopyRoiTo1Var.get(), fp)
    with open('data/CopyRoiTo2.dat', 'wb') as fp:
        pickle.dump(CopyRoiTo2Var.get(), fp)
    with open('data/CopyRoiTo3.dat', 'wb') as fp:
        pickle.dump(CopyRoiTo3Var.get(), fp)
    with open('data/CopyRoiTo4.dat', 'wb') as fp:
        pickle.dump(CopyRoiTo4Var.get(), fp)
    with open('data/CopyRoiTo5.dat', 'wb') as fp:
        pickle.dump(CopyRoiTo5Var.get(), fp)
    return
def Start(): # Accept task parameters
    global Phase, IsHousingAnalysis, SaveTrg, ExperimentStartYear, ExperimentStartMonth, ExperimentStartDay, ExperimentStartHour, ExperimentStartMinute, ExperimentStartSecond  # Global variant outside this define
    RemoveMainCenterWidget()
    RemoveMainRightWidget()
    ExperimentStartYear = TimeNow.year
    ExperimentStartMonth = TimeNow.month
    ExperimentStartDay = TimeNow.day
    ExperimentStartHour = TimeNow.hour
    ExperimentStartMinute = TimeNow.minute
    ExperimentStartSecond = TimeNow.second + (TimeNow.microsecond // 1000) /1000
    SetTaskStartTime()
    SaveTrg = 1
    Phase += 1
    return
def StartNow(): # Manual task starting, tagg
    global Phase, IsHousingAnalysis, TaskStartedYear, TaskStartedMonth, TaskStartedDay, TaskStartedHour, TaskStartedMinute, TaskStartedSecond, SaveTrg, bStartNow, bTimePlus, bTimeMinus, bBackToPara, IsTouchWindowOn, TouchWindowToggle, SingleMonitorMode

    if os.path.isdir(Path):
        print(f"Folder exists: {Path}")
        RemoveMainCenterWidget()
        TaskStartedYear = TimeNow.year
        TaskStartedMonth = TimeNow.month
        TaskStartedDay = TimeNow.day
        TaskStartedHour = TimeNow.hour
        TaskStartedMinute = TimeNow.minute
        TaskStartedSecond = TimeNow.second + (TimeNow.microsecond // 1000) / 1000
        SaveTrg = 1
        if SingleMonitorMode == 0:
            if IsTouchWindowOn != 1:
                TouchWindowToggle = 1  # Turn on touch monitor
        Phase += 1
    else:
        print(f"Folder not found: {Path}")
        messagebox.showinfo("Alert", "The save folder path has not been found!")
    return
def IsStartTime():
    global TaskStartHour, TaskStartMinute, IsHousingAnalysis
    ReturnValue = 0
    if IsHousingAnalysis==1:
        for i in range(4):
            if TaskStartHour[i]==TimeNow.hour and TaskStartMinute[i]==TimeNow.minute:
                ReturnValue=1
                print("Task start!")
    return ReturnValue
def SetTaskStartTime(): #
    global TaskStartHour, TaskStartMinute
    for i in range(4):
        if (i==0 and TaskStartTime1Var.get()!="") or (i==1 and TaskStartTime2Var.get()!="") or (i==2 and TaskStartTime3Var.get()!="") or (i==3 and TaskStartTime4Var.get()!=""):
            if i==0:
                String=TaskStartTime1Var.get()
            if i==1:
                String=TaskStartTime2Var.get()
            if i==2:
                String=TaskStartTime3Var.get()
            if i==3:
                String=TaskStartTime4Var.get()
            StringArray=String.split(':')
            if StringArray[0].isdigit():  # Check whether the string is digit
                TaskStartHour[i] = int(StringArray[0])
            if StringArray[1].isdigit():  # Check whether the string is digit
                TaskStartMinute[i] = int(StringArray[1])
    return
def SetLightCycleTime():
    global LightPhaseOnsetHour, LightPhaseOnsetMinute,  DarkPhaseOnsetHour, DarkPhaseOnsetMinute
    String = LightPhaseOnsetTimeVar.get()
    StringArray = String.split(':')
    if StringArray[0].isdigit():  # Check whether the string is digit
        LightPhaseOnsetHour = int(StringArray[0])
    if StringArray[1].isdigit():  # Check whether the string is digit
        LightPhaseOnsetMinute = int(StringArray[1])

    String = DarkPhaseOnsetTimeVar.get()
    StringArray = String.split(':')
    if StringArray[0].isdigit():  # Check whether the string is digit
        DarkPhaseOnsetHour = int(StringArray[0])
    if StringArray[1].isdigit():  # Check whether the string is digit
        DarkPhaseOnsetMinute = int(StringArray[1])
    return
def GetExperimentStartYear():
    global ExperimentStartYear
    return ExperimentStartYear
def GetExperimentStartMonth():
    global ExperimentStartMonth
    return ExperimentStartMonth
def GetExperimentStartDay():
    global ExperimentStartDay
    return ExperimentStartDay
def GetExperimentStartHour():
    global ExperimentStartHour
    return ExperimentStartHour
def GetExperimentStartMinute():
    global ExperimentStartMinute
    return ExperimentStartMinute
def GetExperimentStartSecond():
    global ExperimentStartSecond
    return ExperimentStartSecond

def GetTaskStartedYear():
    global TaskStartedYear
    return TaskStartedYear
def GetTaskStartedMonth():
    global TaskStartedMonth
    return TaskStartedMonth
def GetTaskStartedDay():
    global TaskStartedDay
    return TaskStartedDay
def GetTaskStartedHour():
    global TaskStartedHour
    return TaskStartedHour
def GetTaskStartedMinute():
    global TaskStartedMinute
    return TaskStartedMinute
def GetTaskStartedSecond():
    global TaskStartedSecond
    return TaskStartedSecond

def StartLickRecording():
    global StartLickRecordingTrg
    StartLickRecordingTrg = 1
    return
def EndLickRecording():
    global EndLickRecordingTrg
    EndLickRecordingTrg = 1
    return
def Back(): # Back to task selection
    global Phase, ManualPanelOnTrg, MainWindowRightFrameX, MainWindowRightFrameY, MainWindowRightFrameWidth, MainWindowRightFrameHeight, Task, BackButtonTrg
    SaveGeneralParameter()
    RemoveMainRightWidget()
    RemoveMainCenterWidget()
    Task = 0
    MainWindowRightFrame.place(x=MainWindowRightFrameX, y=MainWindowRightFrameY, width=MainWindowRightFrameWidth, height=MainWindowRightFrameHeight)  #
    PutTaskButton()
    RemoveRoiWidget()
    # Delete panel which is created by manual panel display button
    ManualPanelOnTrg = 1
    ToggleManualPanel()
    BackButtonTrg = 1
    Phase = 0
    return
def GetBackButtonStat():  # Check whether "Back" button is clicked
    global BackButtonTrg
    ReturnValue = 0
    if BackButtonTrg==1:
        ReturnValue=1
        BackButtonTrg = 0
    return ReturnValue
def GetEndTaskNowButtonStat():
    global EndTaskNowButtonTrg
    ReturnValue = EndTaskNowButtonTrg
    EndTaskNowButtonTrg = 0
    return ReturnValue

def Setting():   #
    global Phase
    if Phase == 0 or Phase == -99: # If phase is task selection or setting
        if Phase == 0:
            RemoveMainRightWidget()
            MainWindowRightFrame.place(x=MainWindowRightFrameX, y=MainWindowRightFrameY, width=MainWindowRightFrameWidth, height=MainWindowRightFrameHeight)  #
            PutSetting1Item()
            Phase = -99   # Show setting items
            #Trg=1
        '''if Phase == -99 and Trg==0:
            SaveGeneralParameter()
            MainWindowRightFrame.place(x=MainWindowRightFrameX , y=MainWindowRightFrameY, width=MainWindowRightFrameWidth, height=MainWindowRightFrameHeight)  #
            SetLightCycleTime()
            PutTaskButton()
            Phase = 0   # Show task selection items
        '''
    return

def Setting2():   #
    global Phase
    if Phase == 0 or Phase == -100: # If phase is task selection or setting2
        if Phase == 0:
            RemoveMainRightWidget()
            MainWindowRightFrame.place(x=MainWindowRightFrameX, y=MainWindowRightFrameY, width=MainWindowRightFrameWidth, height=MainWindowRightFrameHeight)  #
            PutSetting2Item()
            Phase = -100   # Show setting items
    return

def CopyRoi():
    global Phase
    Phase=-98   #ROI copy mode
    SaveGeneralParameter()
    RemoveMainCenterWidget()
    RemoveMainRightWidget()

    ColumnWidth=14
    X = 30
    Y = 0
    YShift = 25
    mCopyFrom = ttk.Label(MainWindowRightFrame, text='Copy From (task #)').place(x=X, y=Y)
    Y += YShift*3
    iCopyFrom = ttk.Entry(MainWindowRightFrame, textvariable= CopyRoiFromVar, width=ColumnWidth).place(x=X, y=Y)  # Place entry field

    X=230
    Y=0
    mCopyTo = ttk.Label(MainWindowRightFrame, text='Copy To (task #)').place(x=X, y=Y)
    Y += YShift
    iCopyTo1 = ttk.Entry(MainWindowRightFrame, textvariable=CopyRoiTo1Var, width=ColumnWidth).place(x=X, y=Y)  # Place entry field
    Y += YShift
    iCopyTo2 = ttk.Entry(MainWindowRightFrame, textvariable=CopyRoiTo2Var, width=ColumnWidth).place(x=X, y=Y)  # Place entry field
    Y += YShift
    iCopyTo3 = ttk.Entry(MainWindowRightFrame, textvariable=CopyRoiTo3Var, width=ColumnWidth).place(x=X, y=Y)  # Place entry field
    Y += YShift
    iCopyTo4 = ttk.Entry(MainWindowRightFrame, textvariable=CopyRoiTo4Var, width=ColumnWidth).place(x=X, y=Y)  # Place entry field
    Y += YShift
    iCopyTo4 = ttk.Entry(MainWindowRightFrame, textvariable=CopyRoiTo5Var, width=ColumnWidth).place(x=X, y=Y)  # Place entry field

    mArrow = ttk.Label(MainWindowRightFrame, text='-->').place(x=170, y=YShift*3)
    bCopyRoiOk = ttk.Button(MainWindowRightFrame, text='OK', command=DoneCopyRoi).place(x=360, y=YShift*2)
    bCopyRoiOk = ttk.Button(MainWindowRightFrame, text='Cancel', command=CancelCopyRoi).place(x=360, y=YShift * 3)
    return

def DoneCopyRoi():  # If ok button is clicked at copy ROI
    global Phase
    if CopyRoiFromVar.get().isdigit():
        FromTaskID = int(CopyRoiFromVar.get())
    for i in range(5):
        Trg=0
        if i==0 and CopyRoiTo1Var.get().isdigit():
            ToTaskID=int(CopyRoiTo1Var.get())
            Trg=1
        if i==1 and CopyRoiTo2Var.get().isdigit():
            ToTaskID=int(CopyRoiTo2Var.get())
            Trg = 1
        if i==2 and CopyRoiTo3Var.get().isdigit():
            ToTaskID=int(CopyRoiTo3Var.get())
            Trg = 1
        if i==3 and CopyRoiTo4Var.get().isdigit():
            ToTaskID=int(CopyRoiTo4Var.get())
            Trg = 1
        if i==4 and CopyRoiTo5Var.get().isdigit():
            ToTaskID=int(CopyRoiTo5Var.get())
            Trg = 1
        if Trg==1:
            print("Parameters of panels and ROIs are copied from task "+str(FromTaskID)+" to task "+str(ToTaskID))
            for i2 in range(MaxPanelNum):
                PanelUsed[ToTaskID][i2] = PanelUsed[FromTaskID][i2]
                PanelULX[ToTaskID][i2] = PanelULX[FromTaskID][i2]
                PanelULY[ToTaskID][i2] = PanelULY[FromTaskID][i2]
                PanelBRX[ToTaskID][i2] = PanelBRX[FromTaskID][i2]
                PanelBRY[ToTaskID][i2] = PanelBRY[FromTaskID][i2]
            for i2 in range(MaxRoiNum):
                RoiUsed[ToTaskID][i2]=RoiUsed[FromTaskID][i2]

                Roi1X[ToTaskID][i2]=Roi1X[FromTaskID][i2]
                Roi1Y[ToTaskID][i2]=Roi1Y[FromTaskID][i2]
                Roi2X[ToTaskID][i2]=Roi2X[FromTaskID][i2]
                Roi2Y[ToTaskID][i2]=Roi2Y[FromTaskID][i2]

                LightThListVar[ToTaskID][i2].set(str(LightThListVar[FromTaskID][i2].get()))
                DarkThListVar[ToTaskID][i2].set(str(DarkThListVar[FromTaskID][i2].get()))
                NumThListVar[ToTaskID][i2].set(str(NumThListVar[FromTaskID][i2].get()))


    Phase=0
    SaveGeneralParameter()
    RemoveMainCenterWidget()
    RemoveMainRightWidget()
    PutTaskButton()
    return

def CancelCopyRoi():
    global Phase
    Phase = 0
    RemoveMainCenterWidget()
    RemoveMainRightWidget()
    PutTaskButton()
    return

def DoneSetting():  #tagg
    global Phase, RoiDensity
    SaveGeneralParameter()
    RemoveMainRightWidget()
    MainWindowRightFrame.place(x=MainWindowRightFrameX, y=MainWindowRightFrameY, width=MainWindowRightFrameWidth, height=MainWindowRightFrameHeight)  #
    SetLightCycleTime()
    PutTaskButton()
    RoiDensity = float(RoiDensityVar.get())
    if DigitalOut[13]==0:
        RoofLightOff()
    if DigitalOut[13]==1:
        RoofLightOn()

    # CamExposureLight = int(CamExposureLightVar.get())
    # CamExposureDark = int(CamExposureDarkVar.get())
    # if CamExposureFix == 1:
    #     if DigitalOut[13]==1:   # If roof light is tuned on
    #         VideoCapture.set(cv2.CAP_PROP_EXPOSURE, CamExposureLight)
    #     if DigitalOut[13]==0:   # If roof light is tuned on
    #         VideoCapture.set(cv2.CAP_PROP_EXPOSURE, CamExposureDark)

    Phase = 0  # Show task selection items
    return
def SaveTrgOn():
    global SaveTrg
    SaveTrg=1
    SaveGeneralParameter()
    return

def BackToPara():   # Back to parameter input (This is not in use)
    global Phase, ManualPanelOnTrg, MainWindowRightFrameX, MainWindowRightFrameY, MainWindowRightFrameWidth, MainWindowRightFrameHeight
    RemoveMainCenterWidget()
    RemoveMainRightWidget()
    MainWindowRightFrame.place(x=MainWindowRightFrameX, y=MainWindowRightFrameY, width=MainWindowRightFrameWidth, height=MainWindowRightFrameHeight)  #
    PutTaskButton()
    # Delete panel which is created by manual panel display button
    ManualPanelOnTrg = 1
    ToggleManualPanel()
    Phase = 0
    return

def EndTaskNow():   #
    global EndTaskNowButtonTrg
    EndTaskNowButtonTrg=1   # End task WITHOUT automatic task switch
    return

def EndFlagOn():
    global EndFlag
    EndFlag = 1
    RoofLightOff()
    InfraredLightOff()
    ServoPosMiddle(3)  # Move water nozzle to the intermediate position
    return

def donothing():
    return

def SelectPathForSaving():  # Chose foler for saving results
    global Path,VideoWriter
    TouchWindowRoot.geometry('+' + str(ULXofTouchWindow + 2000) + '+' + str(ULYofTouchWindow + 2000))  # Move window
    NewPath=filedialog.askdirectory(initialdir = Path, parent = MainWindowRoot)
    if NewPath!="":
        Path=NewPath
        PathForSaving.set(Path)
        SaveGeneralParameter()
    TouchWindowRoot.geometry('+' + str(ULXofTouchWindow) + '+' + str(ULYofTouchWindow))  # Move window
    #Path="/home/pi/Box/Temp"
    return
def SelectPanel0TexPath():
    global PanelTexturePath
    FileSelectWinRoot = Tk()    # Show file select dialog
    FileSelectWinRoot.withdraw()
    fTyp = [("", "*")]
    iDir = os.path.abspath(os.path.dirname(__file__))
    PanelTexturePath[0]= filedialog.askopenfilename(filetypes=fTyp, initialdir=iDir)    # Get path of the texture
    print("Texture path: " + PanelTexturePath[0])

    SaveGeneralParameter()
    return
def SelectPanel1TexPath():
    global PanelTexturePath
    FileSelectWinRoot = Tk()  # Show file select dialog
    FileSelectWinRoot.withdraw()
    fTyp = [("", "*")]
    iDir = os.path.abspath(os.path.dirname(__file__))
    PanelTexturePath[1] = filedialog.askopenfilename(filetypes=fTyp, initialdir=iDir)  # Get path of the texture
    print("Texture path: " + PanelTexturePath[1])

    SaveGeneralParameter()
    return
def SelectPanel2TexPath():
    global PanelTexturePath
    FileSelectWinRoot = Tk()  # Show file select dialog
    FileSelectWinRoot.withdraw()
    fTyp = [("", "*")]
    iDir = os.path.abspath(os.path.dirname(__file__))
    PanelTexturePath[2] = filedialog.askopenfilename(filetypes=fTyp, initialdir=iDir)  # Get path of the texture
    print("Texture path: " + PanelTexturePath[2])

    SaveGeneralParameter()
    return
def SelectPanel3TexPath():
    global PanelTexturePath
    FileSelectWinRoot = Tk()  # Show file select dialog
    FileSelectWinRoot.withdraw()
    fTyp = [("", "*")]
    iDir = os.path.abspath(os.path.dirname(__file__))
    PanelTexturePath[3] = filedialog.askopenfilename(filetypes=fTyp, initialdir=iDir)  # Get path of the texture
    print("Texture path: " + PanelTexturePath[3])

    SaveGeneralParameter()
    return

def RoiTest(RoiID):  # Turn on ROI detection manually
    global ManualRoiDetectionID,ManualRoiDetectionCnt
    ManualRoiDetectionID = RoiID    # Turn on manual ROI detection
    ManualRoiDetectionCnt = 5
    print("ROI"+str(RoiID)+" is activated manually")
    return

def GetRecordFps():
    global RecordFps
    return RecordFps

def GetRoiSensitivity():    # Return text about sensitivity settings of each ROI
    global MaxRoiNum, Task, RoiUsed
    OutText="\n"
    IsFirst=1
    for i in range(MaxRoiNum):
        if RoiUsed[Task][i]==1:
            if IsFirst==0:
                OutText += "\n"
            OutText += "<ROI"+str(i)+"> Dark "
            OutText += DarkThListVar[Task][i].get()+" Light "
            OutText += LightThListVar[Task][i].get()+" Num "
            OutText += NumThListVar[Task][i].get()
            IsFirst = 0
    return OutText

def GetServoAngle():
    global ServoChNum, ServoGuiEnabled
    OutText = "\n"
    for i in range(ServoChNum):
        if ServoGuiEnabled[i] == 1:
            OutText += "Servo angle(In): "+InAngleVar[i].get()+"    Servo angle(Middle): "+MidAngleVar[i].get()+"  Servo angle(Out): "+OutAngleVar[i].get()+"\n"
    return OutText

def LightCycleControlOn():
    global LightCycleControl
    LightCycleControl=1
    return
def LightCycleControlOff():
    global LightCycleControl
    LightCycleControl = 0
    return
def GetTaskID():   # Return value of "Task" valuable
    global Task
    return Task
def SetTaskNum(ID):   # Set value of "Task" valuable
    global Task
    Task=ID
    return
def GetSaveTrgStat():   # Return value of "SaveTrg" valuable
    global SaveTrg
    ReturnValue=SaveTrg
    SaveTrg=0
    return ReturnValue
def GetRecordingStat():   # Return value of "NowRecording" valuable
    global NowRecording
    return NowRecording
def SetDispVariable(ID,Name,Value):
    global DispVariable
    DispVariable[ID][0] = Name
    DispVariable[ID][1] = Value
    return

def PutTaskButton():
    ButtonWidth = 12
    Row=0
    Column=0
    bTask1 = ttk.Button(MainWindowRightFrame, text='Acclim(1)', command=functools.partial(SwitchToSelectedTask, 1), width=ButtonWidth).grid(row=Row, column=Column)
    Column += 1
    bTask2 = ttk.Button(MainWindowRightFrame, text='VisualDisc(2)', command=functools.partial(SwitchToSelectedTask, 2), width=ButtonWidth).grid(row=Row, column=Column)
    Column += 1
    bTask3 = ttk.Button(MainWindowRightFrame, text='VisualDisc(3)', command=functools.partial(SwitchToSelectedTask, 3), width=ButtonWidth).grid(row=Row, column=Column)
    Column += 1
    bTask4 = ttk.Button(MainWindowRightFrame, text='PressAll(4)', command=functools.partial(SwitchToSelectedTask, 4), width=ButtonWidth).grid(row=Row, column=Column)
    Column += 1
    bTask5 = ttk.Button(MainWindowRightFrame, text='SpatDisc(5)', command=functools.partial(SwitchToSelectedTask, 5), width=ButtonWidth).grid(row=Row, column=Column)
    Column += 1
    bTask6 = ttk.Button(MainWindowRightFrame, text='DNMTP(6)', command=functools.partial(SwitchToSelectedTask, 6), width=ButtonWidth).grid(row=Row, column=Column)
    Column += 1
    bTask7 = ttk.Button(MainWindowRightFrame, text='DNMTP(7)', command=functools.partial(SwitchToSelectedTask, 7), width=ButtonWidth).grid(row=Row, column=Column)
    Column += 1
    bTask8 = ttk.Button(MainWindowRightFrame, text='DAT(8)', command=functools.partial(SwitchToSelectedTask, 8), width=ButtonWidth).grid(row=Row, column=Column)

    Row += 1  # Begin a new line
    Column = 0

    bTask9 = ttk.Button(MainWindowRightFrame, text='PatSep(9)', command=functools.partial(SwitchToSelectedTask, 9), width=ButtonWidth).grid(row=Row, column=Column)
    Column += 1
    bTask10 = ttk.Button(MainWindowRightFrame, text='PatSepT(10)', command=functools.partial(SwitchToSelectedTask, 10), width=ButtonWidth).grid(row=Row, column=Column)
    Column += 1
    bTask11 = ttk.Button(MainWindowRightFrame, text='Go/NoGo(11)', command=functools.partial(SwitchToSelectedTask, 11), width=ButtonWidth).grid(row=Row, column=Column)
    Column += 1
    bTask12 = ttk.Button(MainWindowRightFrame, text='Habit(12)', command=functools.partial(SwitchToSelectedTask, 12), width=ButtonWidth).grid(row=Row, column=Column)
    Column += 1
    bTask13 = ttk.Button(MainWindowRightFrame, text='ProbRevA(13)', command=functools.partial(SwitchToSelectedTask, 13), width=ButtonWidth).grid(row=Row, column=Column)
    Column += 1
    bTask14 = ttk.Button(MainWindowRightFrame, text='ProbRevB(14)', command=functools.partial(SwitchToSelectedTask, 14), width=ButtonWidth).grid(row=Row, column=Column)
    Column += 1
    bTask15 = ttk.Button(MainWindowRightFrame, text='5-CSRTT(15)', command=functools.partial(SwitchToSelectedTask, 15), width=ButtonWidth).grid(row=Row, column=Column)
    Column += 1
    bTask16 = ttk.Button(MainWindowRightFrame, text='LeverCon(16)', command=functools.partial(SwitchToSelectedTask, 16), width=ButtonWidth).grid(row=Row, column=Column)

    Row += 1  # Begin a new line
    Column = 0

    bTask89 = ttk.Button(MainWindowRightFrame, text='Linear(89)', command=functools.partial(SwitchToSelectedTask, 89), width=ButtonWidth).grid(row=Row, column=Column)
    Column += 1
    bTask90 = ttk.Button(MainWindowRightFrame, text='Test(90)', command=functools.partial(SwitchToSelectedTask, 90), width=ButtonWidth).grid(row=Row, column=Column)
    Column += 1
    bTask91 = ttk.Button(MainWindowRightFrame, text='Test2(91)', command=functools.partial(SwitchToSelectedTask, 91), width=ButtonWidth).grid(row=Row, column=Column)
    Column += 1
    bTask92 = ttk.Button(MainWindowRightFrame, text='Test3(92)', command=functools.partial(SwitchToSelectedTask, 92), width=ButtonWidth).grid(row=Row, column=Column)
    Column += 1
    bTask93 = ttk.Button(MainWindowRightFrame, text='Test4(93)', command=functools.partial(SwitchToSelectedTask, 93), width=ButtonWidth).grid(row=Row, column=Column)
    return

def TurnOnRoi():    # Show ROIs
    global ShowRoi
    ShowRoi = 1
    return
def TurnOffRoi():   # Hide ROIs
    global ShowRoi
    ShowRoi=0
    return

def SwitchToSelectedTask(ChosenTask):   # Initialize for the starting of the task
    global Task, Phase, DispVariable
    Task = ChosenTask
    Phase = 0
    RemoveAllDigitalOutGui()
    PutDigitalOutGui(10)
    PutDigitalOutGui(12)
    PutDigitalOutGui(13)
    RemoveAllRoiGui()  # Delete all ROIs which already created
    TurnOnRoi()
    DispVariable = [['' for i in range(2)] for j in range(10)]  # Use can show variables of their task through this variable
    for i in range(MaxRoiNum):
        RoiInitDark[i] = 0
        RoiInitLight[i] = 0

    if Task==1:
        Task1()
    if Task==2:
        Task2()
    if Task==3:
        Task3()
    if Task==4:
        Task4()
    if Task==5:
        Task5()
    if Task == 6:
        Task6()
    if Task==7:
        Task7()
    if Task==8:
        Task8()
    if Task==9:
        Task9()
    if Task==10:
        Task10()
    if Task==11:
        Task11()
    if Task==12:
        Task12()
    if Task==13:
        Task13()
    if Task==14:
        Task14()
    if Task==15:
        Task15()
    if Task==16:
        Task16()
    if Task == 89:
        Task89()
    if Task == 90:
        Task90()
    if Task == 91:
        Task91()
    if Task == 92:
        Task92()
    if Task == 93:
        Task93()
    return



def PutSetting1Item():   # Put items for setting
    ColumnWidth = 14
    Row = 0  # Begin a new line
    Column = 0


    mCameraCaptureFreq = ttk.Label(MainWindowRightFrame, text='Camera capture freq', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
    iCameraCaptureFreq = ttk.Entry(MainWindowRightFrame, textvariable=CameraCaptureFreqVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
    Column += 1  # Shift column
    mTouchX_Shift = ttk.Label(MainWindowRightFrame, text='TouchOffset_X', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
    iTouchX_Shift = ttk.Entry(MainWindowRightFrame, textvariable=TouchX_ShiftVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
    Column += 1  # Shift column
    mTouchY_Shift = ttk.Label(MainWindowRightFrame, text='TouchOffset_Y', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
    iTouchY_Shift = ttk.Entry(MainWindowRightFrame, textvariable=TouchY_ShiftVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
    Column += 1  # Shift column
    mTouchX_Scale = ttk.Label(MainWindowRightFrame, text='TouchRatio_X', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
    iTouchX_Scale = ttk.Entry(MainWindowRightFrame, textvariable=TouchX_ScaleVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
    Column += 1  # Shift column
    mTouchY_Scale = ttk.Label(MainWindowRightFrame, text='TouchRatio_Y', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
    iTouchY_Scale = ttk.Entry(MainWindowRightFrame, textvariable=TouchY_ScaleVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field

    Row += 2  # Begin a new line
    Column = 0

    mArduinoConnection = ttk.Label(MainWindowRightFrame, text='Arduino detect', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
    tArduinoConnection = OptionMenu(MainWindowRightFrame, ArduinoConnectionVar, "ON", "OFF").grid(row=Row+1, column=Column)  # Put dropdown list
    Column += 1  # Shift column
    mMouseDebugMode = ttk.Label(MainWindowRightFrame, text='Mouse debug', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
    tMouseDebugMode = OptionMenu(MainWindowRightFrame, MouseDebugModeVar, "ON", "OFF").grid(row=Row+1, column=Column)  # Put dropdown list
    Column += 1  # Shift column
    mPanel0Texture = ttk.Label(MainWindowRightFrame, text='Texture #0', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
    bPanel0Texture = ttk.Button(MainWindowRightFrame, text='Select', command=SelectPanel0TexPath)
    bPanel0Texture.grid(row=Row+1, column=Column)  # Place button
    Column += 1  # Shift column
    mPanel1Texture = ttk.Label(MainWindowRightFrame, text='Texture #1', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
    bPanel1Texture = ttk.Button(MainWindowRightFrame, text='Select', command=SelectPanel1TexPath)
    bPanel1Texture.grid(row=Row+1, column=Column)  # Place button
    Column += 1  # Shift column
    mPanel2Texture = ttk.Label(MainWindowRightFrame, text='Texture #2', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
    bPanel2Texture = ttk.Button(MainWindowRightFrame, text='Select', command=SelectPanel2TexPath)
    bPanel2Texture.grid(row=Row+1, column=Column)  # Place button
    Column += 1  # Shift column
    mPanel3Texture = ttk.Label(MainWindowRightFrame, text='Texture #3', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
    bPanel3Texture = ttk.Button(MainWindowRightFrame, text='Select', command=SelectPanel3TexPath)
    bPanel3Texture.grid(row=Row+1, column=Column)  # Place button
    Column += 1  # Shift column
    mCableDetectCorrValue = ttk.Label(MainWindowRightFrame, text='CableDetectValue', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
    iCableDetectCorrValue = ttk.Entry(MainWindowRightFrame, textvariable=CableDetectCorrValueVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field

    Row += 2  # Begin a new line
    Column = 0

    mTaskStart1 = ttk.Label(MainWindowRightFrame, text='TaskStart1(h:m)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
    iTaskStart1 = ttk.Entry(MainWindowRightFrame, textvariable=TaskStartTime1Var, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
    Column += 1  # Shift column
    mTaskStart2 = ttk.Label(MainWindowRightFrame, text='TaskStart2', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
    iTaskStart2 = ttk.Entry(MainWindowRightFrame, textvariable=TaskStartTime2Var, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
    Column += 1  # Shift column
    mTaskStart3 = ttk.Label(MainWindowRightFrame, text='TaskStart3', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
    iTaskStart3 = ttk.Entry(MainWindowRightFrame, textvariable=TaskStartTime3Var, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
    Column += 1  # Shift column
    mTaskStart4 = ttk.Label(MainWindowRightFrame, text='TaskStart4', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
    iTaskStart4 = ttk.Entry(MainWindowRightFrame, textvariable=TaskStartTime4Var, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
    Column += 1  # Shift column
    mLightPhaseOnsetTime = ttk.Label(MainWindowRightFrame, text='Light-phase onset', width=15).grid(row=Row, column=Column, sticky=W)    # Put label
    iLightPhaseOnsetTime = ttk.Entry(MainWindowRightFrame, textvariable=LightPhaseOnsetTimeVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
    Column += 1  # Shift column
    mDarkPhaseOnsetTime = ttk.Label(MainWindowRightFrame, text='Dark-phase onset', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
    iDarkPhaseOnsetTime = ttk.Entry(MainWindowRightFrame, textvariable=DarkPhaseOnsetTimeVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
    Column += 1  # Shift column

    bPanel2Texture = ttk.Button(MainWindowRightFrame, text='OK', command=DoneSetting)
    bPanel2Texture.grid(row=Row + 1, column=Column)  # Place button
    return


def PutSetting2Item():   # Put items for setting
    ColumnWidth = 16
    Row = 0  # Begin a new line
    Column = 0

    mRecipientAddress = ttk.Label(MainWindowRightFrame, text='Recipient address', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
    iRecipientAddress = ttk.Entry(MainWindowRightFrame, textvariable=RecipientAddressVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
    Column += 1  # Shift column
    mSenderAddress = ttk.Label(MainWindowRightFrame, text='Sender address', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
    iSenderAddress = ttk.Entry(MainWindowRightFrame, textvariable=SenderAddressVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
    Column += 1  # Shift column
    mSenderPassword = ttk.Label(MainWindowRightFrame, text='SMTP password', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
    iSenderPassword = ttk.Entry(MainWindowRightFrame, textvariable=SenderPasswordVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
    Column += 1  # Shift column
    mSmtpServer = ttk.Label(MainWindowRightFrame, text='SMTP address', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
    iSmtpServer = ttk.Entry(MainWindowRightFrame, textvariable=SmtpServerVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
    Column += 1  # Shift column
    mSmtpPort = ttk.Label(MainWindowRightFrame, text='SMTP port', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
    iSmtpPort = ttk.Entry(MainWindowRightFrame, textvariable=SmtpPortVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
    Column += 1  # Shift column
    mSecurityType = ttk.Label(MainWindowRightFrame, text='Security type', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
    tSecurityType = OptionMenu(MainWindowRightFrame, SecurityTypeVar, "TLS", "SSL").grid(row=Row + 1, column=Column)  # Put dropdown list
    Column += 1  # Shift column

    Row += 2  # Begin a new line
    Column = 0

    mRoiDensity = ttk.Label(MainWindowRightFrame, text='RoiDensity', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
    iRoiDensity = ttk.Entry(MainWindowRightFrame, textvariable=RoiDensityVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
    Column += 1  # Shift column
    mTouchOffTime = ttk.Label(MainWindowRightFrame, text='TouchOffTime(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
    iTouchOffTime = ttk.Entry(MainWindowRightFrame, textvariable= TouchOffTimeVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
    Column += 1  # Shift column
    mMovieWidth = ttk.Label(MainWindowRightFrame, text='Movie width(pixel)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
    iMovieWidth = ttk.Entry(MainWindowRightFrame, textvariable=MovieWidthVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
    Column += 1  # Shift column
    mMovieHeight = ttk.Label(MainWindowRightFrame, text='Movie height(pixel)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
    iMovieHeight = ttk.Entry(MainWindowRightFrame, textvariable=MovieHeightVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
    Column += 1  # Shift column
    mRecordFps = ttk.Label(MainWindowRightFrame, text='RecordFPS', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
    iRecordFps = ttk.Entry(MainWindowRightFrame, textvariable=RecordFpsVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field


    Row += 2  # Begin a new line
    Column = 0
    #tagg
    mDeviceName = ttk.Label(MainWindowRightFrame, text='Device name', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
    iDeviceName = ttk.Entry(MainWindowRightFrame, textvariable=DeviceNameVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
    Column += 1  # Shift column
    if RaspberryMode == 0:
        mCamExposureLight = ttk.Label(MainWindowRightFrame, text='CamExpL(-16~0)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
    if RaspberryMode == 1:
        mCamExposureLight = ttk.Label(MainWindowRightFrame, text='CamExpL(msec)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
    iCamExposureLight = ttk.Entry(MainWindowRightFrame, textvariable=CamExposureLightVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
    Column += 1  # Shift column
    if RaspberryMode == 0:
        mCamExposureDark = ttk.Label(MainWindowRightFrame, text='CamExpD(-16~0)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
    if RaspberryMode == 1:
        mCamExposureDark = ttk.Label(MainWindowRightFrame, text='CamExpD(msec)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
    iCamExposureDark = ttk.Entry(MainWindowRightFrame, textvariable=CamExposureDarkVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
    Column += 1  # Shift column
    bPanel2Texture = ttk.Button(MainWindowRightFrame, text='OK', command=DoneSetting)
    bPanel2Texture.grid(row=Row + 1, column=Column)  # Place button

    return



'''
def PutAllPanel():  # Show all panels on the monitor
    for i in range(0, MaxPanelNum):
        ULX = PanelULX[Task][i]
        ULY = PanelULY[Task][i]
        BRX = PanelBRX[Task][i]
        BRY = PanelBRY[Task][i]
        if ULX!=0 or ULY!=0 or BRX!=0 or BRY!=0:
            TouchPanelRef[i] = CanvasTouchWindow.create_rectangle(ULX, ULY, BRX, BRY, fill='white')  # Draw current panel
    return
'''
def PutStartBackButton():   # Put start and back button
    global MainWindowRightFrameX, MainWindowRightFrameY, MainWindowRightFrameWidth, MainWindowRightFrameHeight
    MainWindowCenterFrame.place(x=MainWindowCenterFrameX, y=MainWindowCenterFrameY, width=MainWindowCenterFrameWidth, height=MainWindowCenterFrameHeight)  #
    MainWindowRightFrame.place(x=MainWindowRightFrameX+100, y=MainWindowRightFrameY, width=MainWindowRightFrameWidth, height=MainWindowRightFrameHeight)  #
    bStart = ttk.Button(MainWindowCenterFrame, text='Start', command=Start)
    bStart.place(x=0, y=0, width=80)
    bAdjustPanel = ttk.Button(MainWindowCenterFrame, text='AdjustPanel', command=SetPanel)
    bAdjustPanel.place(x=0, y=25, width=80)
    bBack = ttk.Button(MainWindowCenterFrame, text='Back', command=Back)
    bBack.place(x=0, y=50, width=80)
    return

def PutPreTaskButton():
    global bStartNow, bTimePlus, bTimeMinus, bBackToPara, bStartNow, bTimePlus
    bStartNow = ttk.Button(MainWindowCenterFrame, text='StartNow', command=StartNow)
    bStartNow.grid(row=0, column=0)
    #bTimePlus = ttk.Button(MainWindowRightFrame, text='+1 hour', command=Back)
    #bTimePlus.grid(row=1, column=0)
    #bTimeMinus = ttk.Button(MainWindowRightFrame, text='-1 hour', command=Back)
    #bTimeMinus.grid(row=2, column=0)
    bBackToPara = ttk.Button(MainWindowCenterFrame, text='Back', command=BackToPara)
    bBackToPara.grid(row=1, column=0)
    return
def PutEndTaskNowButton():
    global IsThereEndTaskNowButton, bEndTaskNow
    bEndTaskNow = ttk.Button(MainWindowCenterFrame, text='EndTask', command=EndTaskNow)
    bEndTaskNow.grid(row=0, column=0)
    IsThereEndTaskNowButton=1
    return

def PutServoGui(Ch):   #
    global ServoGuiLabeled, ServoUsed, ServoGuiEnabled
    ServoGuiEnabled[Ch] = 1
    if ServoGuiLabeled==0:
        mInAngle = ttk.Label(ServoWindowFrame1, text='In') # Put labels
        mInAngle.grid(row=0, column=1, sticky=W)
        mMidAngle = ttk.Label(ServoWindowFrame1, text='Mid')
        mMidAngle.grid(row=0, column=2, sticky=W)
        mOutAngle = ttk.Label(ServoWindowFrame1, text='Out')
        mOutAngle.grid(row=0, column=3, sticky=W)
    mServoGui = ttk.Label(ServoWindowFrame1, text="Ch"+str(Ch))
    mServoGui.grid(row=Ch, column=0, sticky=W)

    iInAngle = ttk.Entry(ServoWindowFrame1, textvariable=InAngleVar[Ch], width=4)
    iInAngle.grid(row=Ch, column=1, sticky=W)
    iMidAngle = ttk.Entry(ServoWindowFrame1, textvariable=MidAngleVar[Ch], width=4)
    iMidAngle.grid(row=Ch, column=2, sticky=W)
    iOutAngle = ttk.Entry(ServoWindowFrame1, textvariable=OutAngleVar[Ch], width=4)
    iOutAngle.grid(row=Ch, column=3, sticky=W)


    bIn = ttk.Button(ServoWindowFrame1, text="In", command=functools.partial(ServoPosInside, Ch), width=3)
    bIn.grid(row=Ch, column=4)
    bMid = ttk.Button(ServoWindowFrame1, text="Mid", command = functools.partial(ServoPosMiddle, Ch), width = 4)
    bMid.grid(row=Ch, column=5)
    bOut = ttk.Button(ServoWindowFrame1, text="Out", command = functools.partial(ServoPosOutside, Ch), width = 4)
    bOut.grid(row=Ch, column=6)

    return

def RemoveAllRoiGui():   #
    global RoiGuiLabeled, Task
    ChildWidget = RoiWindowFrame.winfo_children()
    for ChildWidget in ChildWidget:
        ChildWidget.destroy()
    for i in range(MaxPanelNum):
        RoiUsed[Task][i]=0
    RoiGuiLabeled=0
    return

def RemoveAllServoGui():   #
    global ServoGuiLabeled, ServoGuiEnabled, ServoChNum
    for i in range(ServoChNum):
        ServoGuiEnabled[i] = 0
    ChildWidget = ServoWindowFrame1.winfo_children()
    for ChildWidget in ChildWidget:
        ChildWidget.destroy()
    ServoGuiLabeled = 0
    return

def PutDigitalOutGui(Ch):  #
    global mDigitalOut, DigitalOutEnabled, DigitalOut
    bToggleDigitalOut = ttk.Button(DOutWindowFrame, text="Ch" + str(Ch), command=functools.partial(ToggleDigitalOut, Ch), width=6)
    bToggleDigitalOut.grid(row=Ch, column=0)
    if DigitalOut[Ch] == 0:
        mDigitalOut[Ch] = ttk.Label(DOutWindowFrame, text="OFF")
    if DigitalOut[Ch] == 1:
        mDigitalOut[Ch] = ttk.Label(DOutWindowFrame, text="ON")
    mDigitalOut[Ch].grid(row=Ch, column=1, sticky=W)
    DigitalOutEnabled[Ch] = 1
    return

def RemoveAllDigitalOutGui():
    global DigitalOutEnabled
    ChildWidget = DOutWindowFrame.winfo_children()
    for ChildWidget in ChildWidget:
        ChildWidget.destroy()
    for i in range(DigitalOutChNum):
        DigitalOutEnabled[i] = 0
    return

def UpdateDigitalOutGui():
    global DigitalOutEnabled, DigitalOut, mDigitalOut, DigitalOutChNum
    for i in range(DigitalOutChNum):
        if DigitalOutEnabled[i]==1:
            if DigitalOut[i] == 0:
                #pass
                mDigitalOut[i]["text"]="OFF"
            if DigitalOut[i] == 1:
                #pass
                mDigitalOut[i]["text"]="ON"
            mDigitalOut[i].grid(row=i, column=1, sticky=W)
    return

def PutRoiGui(P1,P2,P3,P4):  #
    global RoiEntryWidth,Task, RaspberryMode, RoiUsed, MaxRoiNum, RoiGuiLabeled, RoiProperty, RoiUsed
    if TouchDetectSensorType==0 or P1==19:
        if RoiGuiLabeled == 0:
            RoiGuiLabeled = 1
            mDarkTh = ttk.Label(RoiWindowFrame, text='Dark')
            mDarkTh.grid(row=0, column=1, sticky=W)
            mLightTh = ttk.Label(RoiWindowFrame, text='Light')
            mLightTh.grid(row=0, column=2, sticky=W)
            mNumTh = ttk.Label(RoiWindowFrame, text='Num')
            mNumTh.grid(row=0, column=3, sticky=W)
            #print("label write")
            #mRoiNameList = [0] * MaxRoiNum
            #iLightThList = [0] * MaxRoiNum
            #iDarkThList = [0] * MaxRoiNum
            #iNumThList  = [0] * MaxRoiNum
            #bRoiTest = [0] * MaxRoiNum

        RoiUsed[Task][P1] = 1
        RoiProperty[P1][0] = P2  # Set nosepoke detection mode
        RoiProperty[P1][1] = P3  # Set threshold direction
        RoiProperty[P1][2] = P4  # Set whether this ROI shows detection symbol

        mRoiNameList = ttk.Label(RoiWindowFrame, text='Panel' + str(P1))
        mRoiNameList.grid(row=P1 + 1, column=0)
        iLightThList = ttk.Entry(RoiWindowFrame, textvariable=LightThListVar[Task][P1], width=RoiEntryWidth)
        iLightThList.grid(row=P1 + 1, column=2)
        iDarkThList = ttk.Entry(RoiWindowFrame, textvariable=DarkThListVar[Task][P1], width=RoiEntryWidth)
        iDarkThList.grid(row=P1 + 1, column=1, sticky=W)
        iNumThList = ttk.Entry(RoiWindowFrame, textvariable=NumThListVar[Task][P1], width=RoiEntryWidth)
        iNumThList.grid(row=P1 + 1, column=3)
        bRoiTest = ttk.Button(RoiWindowFrame, text='Test', command=functools.partial(RoiTest, P1), width=4)
        bRoiTest.grid(row=P1 + 1, column=4)

    return

def RemoveEndTaskNowButton():
    global IsThereEndTaskNowButton, bEndTaskNow
    bEndTaskNow.destroy()
    IsThereEndTaskNowButton=0
    return
def RemoveMainCenterWidget(): # Destroy all task buttons
    global MainWindowCenterFrame
    ChildWidget = MainWindowCenterFrame.winfo_children()
    for ChildWidget in ChildWidget:
        ChildWidget.destroy()
    return
def RemoveMainRightWidget(): # Destroy all task buttons
    global MainWindowRightFrame
    ChildWidget = MainWindowRightFrame.winfo_children()
    for ChildWidget in ChildWidget:
        ChildWidget.destroy()
    return
def RemoveRoiWidget(): # Destroy all task buttons
    global RoiWindowFrame
    ChildWidget = RoiWindowFrame.winfo_children()
    for ChildWidget in ChildWidget:
        ChildWidget.destroy()
    mBlank = ttk.Label(RoiWindowFrame, text='')
    mBlank.grid(row=0, column=0, sticky=W)
    return
def MoveCrossFireUp():  # For panel position setting
    global CrossFireY
    CanvasTouchWindow.move(HorizontalLine, 0.0, -CrossFireMoveDistance)
    return
def MoveCrossFireRight():   # For panel position setting
    global CrossFireX
    CanvasTouchWindow.move(VerticalLine, CrossFireMoveDistance, 0.0)
    return
def MoveCrossFireLeft():  # For panel position setting
    global CrossFireX
    CanvasTouchWindow.move(VerticalLine, -CrossFireMoveDistance, 0.0)
    return
def MoveCrossFireDown():  # For panel position setting
    global CrossFireY
    CanvasTouchWindow.move(HorizontalLine, 0.0, CrossFireMoveDistance)
    return
def CoarseMode():  # For panel position setting
    global CrossFireMoveDistance
    CrossFireMoveDistance += 10.0
    if CrossFireMoveDistance > 50.0:
        CrossFireMoveDistance = 50.0
    return
def FineMode():  # For panel position setting
    global CrossFireMoveDistance
    CrossFireMoveDistance -= 10.0
    if CrossFireMoveDistance < 2.0:
        CrossFireMoveDistance = 2.0
    return
def SetPanelPos(): # Go to the next panel position setting
    global PanelSetPhase, Init, Task, CurrentPanelNum, PanelULX, PanelULY, VerticalLine, HorizontalLine, TouchPanelRef
    Trg=0
    if PanelSetPhase == 0: # If set button is clicked during setting of upper left position of the touch panel
        WedgetPos = CanvasTouchWindow.coords(VerticalLine)  # Get position of vertical line
        PanelULX[Task][CurrentPanelNum] = WedgetPos[0]  # Get y axis value of the vertical line
        WedgetPos = CanvasTouchWindow.coords(HorizontalLine)
        PanelULY[Task][CurrentPanelNum] = WedgetPos[1]
        NextX = PanelBRX[Task][CurrentPanelNum]
        NextY = PanelBRY[Task][CurrentPanelNum]
        if  NextX==0 and NextY==0:  # If the values are default
            if CurrentPanelNum==0:
                NextX = PanelULX[Task][CurrentPanelNum]+100 # Move the crossfire toward right bottom
                NextY = PanelULY[Task][CurrentPanelNum]+250
            if CurrentPanelNum>0:
                NextX = PanelULX[Task][CurrentPanelNum]+(PanelBRX[Task][CurrentPanelNum-1]-PanelULX[Task][CurrentPanelNum-1])   # Move the crossfire to even the panel size with the previous panel
                NextY = PanelULY[Task][CurrentPanelNum]+(PanelBRY[Task][CurrentPanelNum-1]-PanelULY[Task][CurrentPanelNum-1])
        CanvasTouchWindow.coords(VerticalLine, NextX, 0, NextX, TouchWindowHeight)  # Move vertical line of the cross fire
        CanvasTouchWindow.coords(HorizontalLine, 0, NextY, TouchWindowWidth, NextY)
        SaveGeneralParameter()
        PanelSetPhase += 1
        Init=0
        Trg = 1
    if PanelSetPhase == 1 and Trg==0:  # If set button is clicked during setting of bottom right position of the touch panel
        WedgetPos = CanvasTouchWindow.coords(VerticalLine)
        PanelBRX[Task][CurrentPanelNum] = WedgetPos[0]
        PanelUsed[Task][CurrentPanelNum] = 1
        WedgetPos = CanvasTouchWindow.coords(HorizontalLine)
        PanelBRY[Task][CurrentPanelNum] = WedgetPos[1]
        PosULX = PanelULX[Task][CurrentPanelNum]
        PosULY = PanelULY[Task][CurrentPanelNum]
        PosBRX= PanelBRX[Task][CurrentPanelNum]
        PosBRY = PanelBRY[Task][CurrentPanelNum]
        TouchPanelRef[CurrentPanelNum] = CanvasTouchWindow.create_rectangle(PosULX, PosULY, PosBRX, PosBRY, fill='white')  # Draw current panel

        SaveGeneralParameter()
        PanelSetPhase += 1
        Init = 0
        Trg = 1
    if PanelSetPhase == 2 and Trg==0:  # Continue panel setting
        CurrentPanelNum+=1
        PanelSetPhase=0
        Init = 0
    return
def BackPanelPos(): # Back to the previous panel position setting
    return
def EndPanelSetting():  # Finish panel position setting
    global PanelSetPhase
    PanelSetPhase=-1    # Make flag to finish panel position setting loop
    return

def SetPanel(): # Contain main roop during panel position setting
    global PanelSetPhase, Init, CurrentPanelNum, CrossFireX, CrossFireY, VerticalLine, HorizontalLine, RoiUsed, Roi1X,Roi1Y,Roi2X,Roi2Y
    VerticalLine = CanvasTouchWindow.create_line(100, 0, 100, 1200, fill='cyan', tags="Panel")  # Make vertical line of the cross fire
    HorizontalLine = CanvasTouchWindow.create_line(0, 500, 1200, 500, fill='red', tags="Panel")  # Make horizontal line of the cross fire
    Init=0
    CurrentPanelNum=0
    PanelSetPhase=0
    while EndFlag == 0: # Panel adjust main loop
        OperantHouseUpdate()
        if PanelSetPhase == 0 or PanelSetPhase == 1:    # Move crossfire to indicate panel coordinates
            if Init == 0:
                RemoveMainRightWidget()
                MainWindowRightFrame.place(x=MainWindowRightFrameX, y=MainWindowRightFrameY, anchor="nw", width=MainWindowRightFrameWidth, height=MainWindowRightFrameHeight)
                if PanelSetPhase == 0:
                    PosX = PanelULX[Task][CurrentPanelNum]
                    PosY = PanelULY[Task][CurrentPanelNum]
                    if PosX == 0 and  PosY == 0:    # If there is no data about the panel coordinate
                        if CurrentPanelNum==0:
                            PosX = 200
                            PosY = 400
                        if CurrentPanelNum>0:
                            PosX = PanelBRX[Task][CurrentPanelNum-1]
                            PosY = PanelULY[Task][CurrentPanelNum-1]
                    CanvasTouchWindow.coords(VerticalLine, PosX, 0, PosX, TouchWindowHeight)    # Move vertical line of the cross fire
                    CanvasTouchWindow.coords(HorizontalLine, 0, PosY, TouchWindowWidth, PosY)   # Move horizontal line of the cross fire
                    mCharaMessage = ttk.Label(MainWindowRightFrame, text='Set left upper coordinate of the panel #'+str(CurrentPanelNum)+'.').place(x=CharaMesX, y=CharaMesY)
                if PanelSetPhase == 1:
                    mCharaMessage = ttk.Label(MainWindowRightFrame, text='Set right bottom coordinate of the panel #' + str(CurrentPanelNum) + '.').place(x=CharaMesX, y=CharaMesY)
                mCoordinatesVar = StringVar(MainWindowRoot)
                mCoordinates = ttk.Label(MainWindowRightFrame, textvariable=mCoordinatesVar).place(x=43, y=30)
                bMoveUp = ttk.Button(MainWindowRightFrame, text='Up', command=MoveCrossFireUp).place(x=43, y=50)
                bMoveLeft = ttk.Button(MainWindowRightFrame, text='Left', command=MoveCrossFireLeft).place(x=0, y=75)
                bMoveRight = ttk.Button(MainWindowRightFrame, text='Right', command=MoveCrossFireRight).place(x=86, y=75)
                bMoveDown = ttk.Button(MainWindowRightFrame, text='Down', command=MoveCrossFireDown).place(x=43, y=100)
                bCoarseMode = ttk.Button(MainWindowRightFrame, text='Coarse', command=CoarseMode).place(x=200, y=50)
                bFineMode = ttk.Button(MainWindowRightFrame, text='FineMode', command=FineMode).place(x=200, y=75)
                bSet = ttk.Button(MainWindowRightFrame, text='Set', command=SetPanelPos).place(x=200, y=100)

                Init=1
            WedgetPos = CanvasTouchWindow.coords(VerticalLine)  # Get position of vertical line
            PosX = WedgetPos[0]  # Get y axis value of the vertical line
            WedgetPos = CanvasTouchWindow.coords(HorizontalLine)
            PosY = WedgetPos[1]
            mCoordinatesVar.set('X:'+str(PosX)+'  Y:'+str(PosY))
        if PanelSetPhase == 2:  # Chose whether adjust next panel
            if Init == 0:
                RemoveMainRightWidget()
                mCharaMessage = ttk.Label(MainWindowRightFrame, text='Do you want to set the coordinates of the next panel?').place(x=CharaMesX, y=CharaMesY)
                bSetNextPanelYes = ttk.Button(MainWindowRightFrame, text='Yes', command=SetPanelPos).place(x=0, y=60)
                bSetNextPanelNo = ttk.Button(MainWindowRightFrame, text='No', command=EndPanelSetting).place(x=86, y=60)
                Init = 1
        if PanelSetPhase == -1: # Panel adjust finish process
            RemoveMainRightWidget()
            CanvasTouchWindow.delete(VerticalLine)
            CanvasTouchWindow.delete(HorizontalLine)

            for i in range(0, MaxPanelNum): # Set coordinations of unused panels and ROIs
                if TouchPanelRef[i]:
                    CanvasTouchWindow.delete(TouchPanelRef[i])
                if i > CurrentPanelNum:
                    PanelUsed[Task][i] = 0
                    PanelULX[Task][i] = 0
                    PanelULY[Task][i] = 0
                    PanelBRX[Task][i] = 0
                    PanelBRY[Task][i] = 0

            SaveGeneralParameter()
            TurnOffRoi()
            RemoveRoiWidget()
            PutTaskButton()
            PanelSetPhase = 0
            break
    return

def GetCurrentPanelNum():  # Return panel num which was set in PanelAdjust function
    global Task, PanelUsed, MaxNPanelum
    PanelNum=0
    for i in range(MaxPanelNum):
        if PanelUsed[Task][i] == 1:
            PanelNum+=1
        if PanelUsed[Task][i] == 0:
            break
    return PanelNum


def ServoPosInside(Ch):#
    global IndicatedServoPos, ServoOutputBook, Angle, ServoAngle
    IndicatedServoPos=1
    if InAngleVar[Ch].get()!="":
        Angle = int(InAngleVar[Ch].get())
    Timer_Start(4)  # Timer for servo power
    ServoAngle[Ch]=Angle
    ServoOutputBook = 1  # Book output of servo angle through serial connection
    return
def ServoPosMiddle(Ch):
    global IndicatedServoPos, ServoOutputBook, Angle, ServoAngle
    IndicatedServoPos=0
    if MidAngleVar[Ch].get()!="":
        Angle = int(MidAngleVar[Ch].get())
    Timer_Start(4)
    ServoAngle[Ch] = Angle
    ServoOutputBook = 1  # Book output of servo angle through serial connection
    return
def ServoPosOutside(Ch):
    global IndicatedServoPos, ServoOutputBook, Angle, ServoAngle
    IndicatedServoPos=2
    if OutAngleVar[Ch].get()!="":
        Angle = int(OutAngleVar[Ch].get())
    Timer_Start(4)
    ServoAngle[Ch] = Angle
    ServoOutputBook = 1  # Book output of servo angle through serial connection
    return

def RoofLightOn(): #tagg
    global IndicatedDigitalOut, DigitalPinOutputBook
    IndicatedDigitalOut[13] = 1
    DigitalPinOutputBook = 1  # Book output of digital pin status through serial connection
    NosePokeDetectionTempOff()
    return
def RoofLightOff():
    global IndicatedDigitalOut, DigitalPinOutputBook
    IndicatedDigitalOut[13] = -1
    DigitalPinOutputBook = 1  # Book output of digital pin status through serial connection
    NosePokeDetectionTempOff()
    return

def InfraredLightOn():
    global IndicatedDigitalOut, DigitalPinOutputBook
    IndicatedDigitalOut[12] = 1
    DigitalPinOutputBook = 1  # Book output of digital pin status through serial connection
    return
def InfraredLightOff():
    global IndicatedDigitalOut, DigitalPinOutputBook
    IndicatedDigitalOut[12] = -1
    DigitalPinOutputBook = 1  # Book output of digital pin status through serial connection
    return

def DigitalOutOn(Ch):   #Ch13:roof light 12:IR 11:TTL
    global IndicatedDigitalOut, DigitalPinOutputBook
    IndicatedDigitalOut[Ch]=1
    DigitalPinOutputBook = 1  # Book output of digital pin status through serial connection
    #print("on"+str(Ch))
    return

def DigitalOutOff(Ch):
    global IndicatedDigitalOut, DigitalPinOutputBook
    IndicatedDigitalOut[Ch]=-1
    DigitalPinOutputBook = 1  # Book output of digital pin status through serial connection
    #print("off")
    return

def DigitalOutBlinkOn(Ch):
    global IndicatedDigitalOut, DigitalPinOutputBook
    IndicatedDigitalOut[Ch]=2
    DigitalPinOutputBook = 1  # Book output of digital pin status through serial connection
    return

def DigitalInOn(Ch):
    global IndicatedDigitalIn, InputFromArduinoEnabled, DigitalPinOutputBook
    ser.flushInput()  # Clear input buffer from arduino
    InputFromArduinoEnabled=1
    IndicatedDigitalIn[Ch]=1
    DigitalPinOutputBook = 1  # Book output of digital pin status through serial connection
    return

def DigitalInOff(Ch):   # Restarts of serial transfer from Arduino becomes impossible after using this function somehow
    global IndicatedDigitalIn, InputFromArduinoEnabled, DigitalPinOutputBook
    InputFromArduinoEnabled=0
    IndicatedDigitalIn[Ch]=-1
    DigitalPinOutputBook = 1  # Books output of digital pin status through serial connection
    return

def DetectLeverPress(Ch): # Checks whether lever press occured in the latest frame
    global InputText, InputFromArduinoEnabled, LeverPressNum
    if InputFromArduinoEnabled==0:
        InputFromArduinoEnabled=1
    LeverPressNum = 0
    ReturnValue = -1
    if(InputText):
        #print(InputText)
        #print(type(InputText))
        InputArray = InputText.split(",")
        #print(InputArray)
        for i in range(len(InputArray)):
            if InputArray[i] == "3" and i > 0:
                if InputArray[i - 1]:
                    if int(InputArray[i - 1]) == -7-Ch:
                        ReturnValue = 1
                        print("Lever " + str(Ch) + " press is detected")
                        LeverPressNum+=1
                        break
    return ReturnValue

def DetectLeverPressOld(): # Checks whether lever press occured in the latest frame
    global InputText, InputFromArduinoEnabled, LeverPressNum
    if InputFromArduinoEnabled==0:
        InputFromArduinoEnabled=1
    LeverPressNum = 0
    PressedLeverID = -1
    if(InputText):
        #print(InputText)
        #print(type(InputText))
        InputArray = InputText.split(",")
        #print(InputArray)
        for i in range(len(InputArray)):
            if InputArray[i] == "3" and i > 0:
                if InputArray[i - 1]:
                    if int(InputArray[i - 1]) < -6:
                        PressedLeverID = int(InputArray[i - 1])*-1-7
                        print("Lever " + str(PressedLeverID) + " press is detected")
                        LeverPressNum+=1
                        break
    return PressedLeverID

def DetectLeverPressAnalog(Th): # Checks whether lever press occured in the latest frame
    global InputText, InputFromArduinoEnabled, LeverPressNum
    if InputFromArduinoEnabled==0:
        InputFromArduinoEnabled=1
    LeverPressNum = 0
    PressedLeverID = -1
    if(InputText):
        #print(InputText)
        #print(type(InputText))
        InputArray = InputText.split(",")
        #print(InputArray)
        for i in range(len(InputArray)):
            if i>0 and i < len(InputArray)-1:
                if InputArray[i]!="" and InputArray[i]!="-" and InputArray[i-1]!="" and InputArray[i-1]!="-":
                    if int(InputArray[i]) < Th:  #450 1012
                        #if InputArray[i - 1]!="":
                        if int(InputArray[i - 1]) == Ch*-1-1:
                            if int(InputArray[i - 1]) >= -6:
                                PressedLeverID = int(InputArray[i - 1])*-1-1
                                print("Lever " + str(PressedLeverID) + " press is detected. Value: "+InputArray[i])
                                LeverPressNum+=1
                                break
    return PressedLeverID

def GetRoiDetectNum():
    global RoiDetectNum
    return RoiDetectNum
def ShowTouchSymbol(Num): # Show symbol on the camera window for a certain time
    global TouchSymbolCnt
    TouchSymbolCnt = Num
    return
def NosePokeDetectionTempOff():
    global NosePokeDetectionOn
    NosePokeDetectionOn=0
    Timer_Start(6)
    return
def CreateNormalPanel(id):
    global Task, TouchPanelRef, PanelULX, PanelULY, PanelBRX, PanelBRY, MaxPanelNum, IsHiddenPanel, TypeOfPanel
    TouchPanelRef[id] = CanvasTouchWindow.create_rectangle(PanelULX[Task][id], PanelULY[Task][id], PanelBRX[Task][id], PanelBRY[Task][id], fill='white')  # Create panel
    TypeOfPanel[id] = 0
    CanvasTouchWindow.itemconfigure(TouchPanelRef[id], state='hidden')  # Hide created panel
    IsHiddenPanel[id] = 1
    print('Normal panel '+str(id)+' is created')
    return
def CreateNormalPanel_All():
    global Task, TouchPanelRef, PanelULX, PanelULY, PanelBRX, PanelBRY, MaxPanelNum, IsHiddenPanel, TypeOfPanel
    for i in range(0, MaxPanelNum):
        if PanelUsed[Task][i] == 1:
            TouchPanelRef[i] = CanvasTouchWindow.create_rectangle(PanelULX[Task][i], PanelULY[Task][i], PanelBRX[Task][i], PanelBRY[Task][i], fill='white')  # Create panel
            TypeOfPanel[i] = 0
            CanvasTouchWindow.itemconfigure(TouchPanelRef[i], state='hidden')  # Hide created panel
            IsHiddenPanel[i] = 1
            print('Normal panel is created')
        if PanelUsed[Task][i] == 0:
            break
    return
def CreateBlinkPanel(id):
    global Task, TouchPanelRef, PanelULX, PanelULY, PanelBRX, PanelBRY, MaxPanelNum, IsHiddenPanel, TypeOfPanel, BlinkPanelNum
    TouchPanelRef[id] = CanvasTouchWindow.create_rectangle(PanelULX[Task][id], PanelULY[Task][id], PanelBRX[Task][id], PanelBRY[Task][id], fill='white')  # Create panel
    TypeOfPanel[id] = 1   # Make this as a blink panel
    CanvasTouchWindow.itemconfigure(TouchPanelRef[id], state='hidden')  # Hide created panel
    IsHiddenPanel[id] = 1
    BlinkPanelNum+=1
    print('Blink panel is created')
    return
def CreateBlinkPanel_All():
    global Task, TouchPanelRef, PanelULX, PanelULY, PanelBRX, PanelBRY, MaxPanelNum, IsHiddenPanel, TypeOfPanel, BlinkPanelNum
    for i in range(0, MaxPanelNum):
        if PanelUsed[Task][i] == 1:
            TouchPanelRef[i] = CanvasTouchWindow.create_rectangle(PanelULX[Task][i], PanelULY[Task][i], PanelBRX[Task][i], PanelBRY[Task][i], fill='white')  # Create panel
            TypeOfPanel[i] = 1   # Make this as a blink panel
            CanvasTouchWindow.itemconfigure(TouchPanelRef[i], state='hidden')  # Hide created panel
            IsHiddenPanel[i] = 1
            BlinkPanelNum+=1
            print('Blink panel is created')
        if PanelUsed[Task][i] == 0:
            break
    return
def CreateTexturedPanel(id, TextureID):  # Creates textured panel
    global TypeOfPanel,TouchPanelRef, Task, IsHiddenPanel, PanelULX, PanelULY, PanelTexturePath, PanelTextureImage
    PanelTextureImage[id] = PhotoImage(file=PanelTexturePath[TextureID])  # Load texture file
    TouchPanelRef[id] = CanvasTouchWindow.create_image(PanelULX[Task][id], PanelULY[Task][id], image=PanelTextureImage[id], anchor=NW)   # Create new textured panel
    CanvasTouchWindow.itemconfigure(TouchPanelRef[id], state='hidden')  # Hide created panel
    IsHiddenPanel[id] = 1
    TypeOfPanel[id]=2   # Make this as a textured panel
    print('Textured panel is created')
    return

def CreateTexturedPanel_All(TextureID):  # Creates the same number of the textured panel as user set in the panel adjusting
    global TypeOfPanel,TouchPanelRef, Task, IsHiddenPanel, PanelULX, PanelULY, PanelTexturePath, PanelTextureImage, MaxPanelNum
    for i in range(0, MaxPanelNum):
        if PanelUsed[Task][i] == 1:
            PanelTextureImage[i] = PhotoImage(file=PanelTexturePath[TextureID])  # Load texture file
            TouchPanelRef[i] = CanvasTouchWindow.create_image(PanelULX[Task][i], PanelULY[Task][i], image=PanelTextureImage[i], anchor=NW)   # Create new textured panel
            CanvasTouchWindow.itemconfigure(TouchPanelRef[i], state='hidden')  # Hide created panel
            IsHiddenPanel[i] = 1
            TypeOfPanel[i]=2   # Make this as a textured panel
            print('Textured panel is created')
        if PanelUsed[Task][i] == 0:
            break
    return

def ShowPanel(id):    # Show the given panel for the current task
    global TouchPanelRef, IsHiddenPanel, PanelChanged
    CanvasTouchWindow.itemconfigure(TouchPanelRef[id], state='normal')  # Show created panel
    IsHiddenPanel[id] = 0
    PanelChanged=1
    return
def ShowAllPanel():    # Show all the created panel in the current task
    global TouchPanelRef, IsHiddenPanel, Task, PanelChanged
    for i in range(0, MaxPanelNum):
        if PanelUsed[Task][i]==1:
            CanvasTouchWindow.itemconfigure(TouchPanelRef[i], state='normal')  # Show created panel
            IsHiddenPanel[i] = 0
        if PanelUsed[Task][i] == 0:
            break
    PanelChanged = 1
    return
def HidePanel(id):    # Hide the given panel for the current task
    global TouchPanelRef, IsHiddenPanel, PanelChanged
    CanvasTouchWindow.itemconfigure(TouchPanelRef[id], state='hidden')  # Hide created panel
    IsHiddenPanel[id]=1
    PanelChanged = 1
    return
def HideAllPanel(): # Hide all panels which has been created in this task
    global TouchPanelRef, IsHiddenPanel, MaxPanelNum, Task, PanelChanged
    for i in range(0, MaxPanelNum):
        if PanelUsed[Task][i]==1:
            CanvasTouchWindow.itemconfigure(TouchPanelRef[i], state='hidden')  # Hide created panel
            IsHiddenPanel[i] = 1
        if PanelUsed[Task][i] == 0:
            break
    PanelChanged = 1
    return
def DeletePanel(id):    # Delete the given panel
    global TouchPanelRef, TypeOfPanel, BlinkPanelNum, PanelChanged
    CanvasTouchWindow.delete(TouchPanelRef[id])  # Delete panels
    if TypeOfPanel[i] == 1: # If this is blink panel
        BlinkPanelNum -= 1
    PanelChanged = 1
    return
def DeleteAllPanel():   # Delete all panels which has been created in this task
    global TouchPanelRef, BlinkPanelNum, IsHiddenPanel, TypeOfPanel, PanelChanged
    for i in range(0, MaxPanelNum):
        if TouchPanelRef[i]:
            CanvasTouchWindow.delete(TouchPanelRef[i])  # Delete panels
            IsHiddenPanel[i] = 0
            TypeOfPanel[i] = 0
    BlinkPanelNum = 0
    PanelChanged = 1
    return

def ShowTouchCursor():
    global TouchCursorON
    TouchCursorON = 1
    print('Touch cursor on')
    return
def HideTouchCursor():
    global TouchCursorON
    TouchCursorON = 0
    print('Touch cursor off')
    return

def StartArbitaryWaterSupply(ServoCh, CueCh, IsBlink, millisec):  #
    global AWS_On, AWS_IndicatedDur, AWS_Dur, AWS_PreFrameMilliSec, AWS_CurrFrameMilliSec, AWS_Stat
    AWS_On=1
    AWS_IndicatedDur=millisec
    AWS_Dur = 0
    AWS_PreFrameMilliSec=(TimeNow.hour*60*60*1000) + (TimeNow.minute*60*1000) + (TimeNow.second*1000) + TimeNow.microsecond//1000
    AWS_CurrFrameMilliSec =AWS_PreFrameMilliSec
    AWS_Stat=0
    ServoPosInside(ServoCh)
    if IsBlink == 0:
        DigitalOutOn(CueCh)    # Water cue on
    if IsBlink == 1:
        DigitalOutBlinkOn(CueCh)  # Water cue on
    InfraredLightOn()    # Infrared LED on
    return
def GetArbitaryWaterSupplyStat():
    global AWS_Stat
    ReturnValue = AWS_Stat
    AWS_Stat = 0
    return ReturnValue
def SwitchTask(id): #
    global  AutoTaskSwitchPhase, NextTaskID
    AutoTaskSwitchPhase = 1
    NextTaskID = id
    return

def ToggleTouchWindow():    #Turn on/Turn off the touch window
    global IsTouchWindowOn, TouchWindowToggle
    if IsTouchWindowOn == 1:
        TouchWindowToggle=-1
    if IsTouchWindowOn == -1:
        TouchWindowToggle = 1
    SaveGeneralParameter()
    return

def ToggleCamWin():    #Resize camera window
    global IsCameraWinEnlarged, CameraWindowScaleX, CameraWindowScaleY,CameraWindowPosX, CameraWindowPosY
    if IsCameraWinEnlarged == 1:
        CameraWindowScaleX = 2
        CameraWindowScaleY = 2
        cv2.moveWindow("CameraWindow", CameraWindowPosX, CameraWindowPosY)
    if IsCameraWinEnlarged == -1:
        CameraWindowScaleX = 1
        CameraWindowScaleY = 1
    IsCameraWinEnlarged *= -1
    SaveGeneralParameter()
    return



def Task1():
    global Phase
    Phase0_Init = 0
    Phase1_Init = 0
    Phase2_Init = 0

    while EndFlag == 0:
        OperantHouseUpdate()
        if GetBackButtonStat()==1:    # If "Back" button is clicked
            break   # Back to the task select phase

        if Phase == 0:  # Parameter inputs
            if Phase0_Init == 0:
                # Make GUI for the setting of the parameters for this task
                RemoveMainRightWidget()  # Remove task buttons
                PutStartBackButton()  # Put start/back buttons

                ColumnWidth = 14
                Row = 0  # Begin a new line
                Column = 0

                mTimeLimit = ttk.Label(MainWindowRightFrame, text='TimeLimit(min)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                TimeLimitVar = DoubleVar(MainWindowRoot)
                iTimeLimit = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mNumOfDay = ttk.Label(MainWindowRightFrame, text='NumOfDay', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                NumOfDayVar = IntVar(MainWindowRoot)
                iNumOfDay = ttk.Entry(MainWindowRightFrame, textvariable=NumOfDayVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mNextTask = ttk.Label(MainWindowRightFrame, text='NextTask#', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                NextTaskVar = IntVar(MainWindowRoot)
                iNextTask = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mWaterCueType = ttk.Label(MainWindowRightFrame, text='WaterCueType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                WaterCueTypeVar = StringVar(MainWindowRightFrame)
                tWaterCueType = OptionMenu(MainWindowRightFrame, WaterCueTypeVar, "Normal", "Blink").grid(row=Row+1, column=Column)  # Place entry field

                Str = "ParametersForTask" + str(GetTaskID())

                if os.path.exists(Str + '/TimeLimit.dat') == True:  # If save file exists
                    with open(Str + '/TimeLimit.dat', 'rb') as PickleInst[GetTaskID()]:
                        TimeLimitVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    TimeLimitVar.set(360)  # Default value

                if os.path.exists(Str + '/NumOfDay.dat') == True:  # If save file exists
                    with open(Str + '/NumOfDay.dat', 'rb') as PickleInst[GetTaskID()]:
                        NumOfDayVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NumOfDayVar.set(1)  # Default value

                if os.path.exists(Str + '/NextTask.dat') == True:  # If save file exists
                    with open(Str + '/NextTask.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskVar.set(1)  # Default value
                if os.path.exists(Str + '/WaterCueType.dat') == True:  # If save file exists
                    with open(Str + '/WaterCueType.dat', 'rb') as PickleInst[GetTaskID()]:
                        WaterCueTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    WaterCueTypeVar.set('Normal')  # Default value


                RemoveAllServoGui()
                PutServoGui(3)
                Phase0_Init = 1

        if GetSaveTrgStat() == 1:  # If save trigger is on
            # Parameters of each task are saved into different folder
            Str = "ParametersForTask" + str(GetTaskID())  # Path to the folder for saving of parameters
            if os.path.exists(Str) == False:  # If folder for saving parameters is not exist
                os.mkdir(Str)  # Make folder for saving
            with open(Str + '/TimeLimit.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TimeLimitVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/NumOfDay.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NumOfDayVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/NextTask.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/WaterCueType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(WaterCueTypeVar.get(), PickleInst[GetTaskID()])  # Save

        if Phase == 1:  # Wait for starting of task
            if Phase1_Init == 0:
                PutPreTaskButton()
                mStatusVar = StringVar(MainWindowRoot)
                mStatus = ttk.Label(MainWindowRightFrame, textvariable=mStatusVar)
                mStatus.place(x=10, y=0)
                mOngoingResultVar = StringVar(MainWindowRoot)
                Phase1_Init = 1
                CurrDay = 0
            mStatusVar.set('Acclimation (' + str(GetTaskID()) + ')    Waiting...')
            if IsStartTime() == 1:
                StartNow()
        if Phase == 2:  # During task
            if Phase2_Init == 0:  # Initialization of the task
                PutEndTaskNowButton()
                mStatusVar.set('Acclimation (' + str(GetTaskID()) + ')    Start time ' + str(TaskStartedMonth) + '/' + str(TaskStartedDay) + ' ' + str(TaskStartedHour) + ':' + str(
                    TaskStartedMinute) + '    Running')
                mOngoingResult = ttk.Label(MainWindowRightFrame, textvariable=mOngoingResultVar)
                mOngoingResult.place(x=10, y=18)

                # Convert StringVars of parameters into integer or normal string to use in the following
                TimeLimit = float(TimeLimitVar.get())
                NumOfDay = int(NumOfDayVar.get())
                NextTask = int(NextTaskVar.get())
                WaterCueType = WaterCueTypeVar.get()

                StartLickRecording()
                RoofLightOff()
                InfraredLightOn()
                if WaterCueType == 'Normal':
                    DigitalOutOn(10)
                if WaterCueType == 'Blink':
                    DigitalOutBlinkOn(10)  # Make water cue blink
                ServoPosInside(3)


                # Declar local variables for this task
                LightCycleControlOff()
                StartRecording()  # Start camera capturing and sending of TTL

                Timer_Start(5)  # Task time limit timer start
                ServoPosInside(3)
                Writer_TouchEventTxt = open(
                    Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.txt",
                    'w')  # Initialize the text exporter
                Writer_TouchEventCsv = open(
                    Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.csv",
                    'w')  # Initialize the text exporter
                Phase2 = 0
                Phase2_Init = 1
                print("Task #" + str(GetTaskID()) + " is started at " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(
                    GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

            if Phase2 == 0:  # Initiation of new trial
                if Timer_GetSec(5) >= TimeLimit * 60:  # If time limit is exceeded
                    Timer_End(5)
                    Phase2 = -1

            if Phase2 == -1 or GetEndTaskNowButtonStat() == 1:  # Task finish phase
                LightCycleControlOn()
                ServoPosMiddle(3)
                DigitalOutOff(10)
                DeleteAllPanel()
                InfraredLightOff()
                if GetRecordingStat() == 1:
                    SetEndRecordingTimer(60)
                Writer_TouchEventTxt.write('SessionStartTime: ' + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()) + "\n")
                Writer_TouchEventTxt.write('SessionEndTime: ' + str(TimeNow.month) + '/' + str(TimeNow.day) + ' ' + str(TimeNow.hour) + ':' + str(TimeNow.minute) + ':' + str(TimeNow.second + (TimeNow.microsecond // 1000) / 1000) + "\n")
                Writer_TouchEventTxt.write('CurrDay: ' + str(CurrDay) + "\n")
                Writer_TouchEventTxt.write('TimeLimit: ' + str(TimeLimit) + "\n")
                Writer_TouchEventTxt.write('NumOfDay: ' + str(NumOfDay) + "\n")
                Writer_TouchEventTxt.write('NextTask: ' + str(NextTask) + "\n")
                Writer_TouchEventTxt.write('WaterCueType: ' + str(WaterCueType) + "\n")
                Writer_TouchEventTxt.write('RecordFPS: ' + str(GetRecordFps()) + "\n")
                Writer_TouchEventTxt.write(GetRoiSensitivity() + "\n")
                Writer_TouchEventTxt.write(GetServoAngle() + "\n")

                Writer_TouchEventTxt.close()
                Writer_TouchEventCsv.close()
                EndLickRecording()

                SendMail(DeviceNameVar.get() + ' finished task ' + str(GetTaskID()) + '% Dur:' + str(round(Timer_GetSec(5) / 60, 1)) + ' min', 'The task has been done.')

                if IsHousingAnalysis == 1 and Phase2 == -1:  # If it is housing analysis
                    CurrDay += 1
                    if CurrDay >= NumOfDay:  # If the score exceed the criteria to switch the next task
                        SwitchTask(NextTask)  # Onset task switch trigger
                        print("Task is switched to task#" + str(NextTask) + "  " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

                if IsHousingAnalysis == 0:
                    RoofLightOn()
                Phase = 1  # Go back to the task-waiting phase
                Phase2 = 0
                Phase2_Init = 0
            SetDispVariable(0, 'Phase2', str(Phase2))  # Display "Phase2" value on the main window
    return

def Task2():   # Touch lit panel task
    global Phase
    Phase0_Init=0
    Phase1_Init=0
    Phase2_Init=0
    while EndFlag==0:
        OperantHouseUpdate()
        if GetBackButtonStat()==1:    # If "Back" button is clicked
            break   # Back to the task select phase
        if Phase == 0:  # Parameter inputs
            if Phase0_Init == 0:
                # Make GUI for the setting of the parameters for this task
                RemoveMainRightWidget() # Remove task buttons
                PutStartBackButton()    # Put start/back buttons

                ColumnWidth = 14
                Row = 0  # Begin a new line
                Column = 0
                mMaxCorrectNum = ttk.Label(MainWindowRightFrame, text='MaxCorrectNum', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                MaxCorrectNumVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iMaxCorrectNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxCorrectNumVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mMaxTrialNum = ttk.Label(MainWindowRightFrame, text='MaxTrialNum', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                MaxTrialNumVar = IntVar(MainWindowRoot)
                iMaxTrialNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxTrialNumVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mTimeLimit = ttk.Label(MainWindowRightFrame, text='TimeLimit(min)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                TimeLimitVar = DoubleVar(MainWindowRoot)
                iTimeLimit = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mPunishDur = ttk.Label(MainWindowRightFrame, text='PunishDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                PunishDurVar = DoubleVar(MainWindowRoot)
                iPunishDur = ttk.Entry(MainWindowRightFrame, textvariable=PunishDurVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mIti = ttk.Label(MainWindowRightFrame, text='ITI(s)', width=11).grid(row=Row, column=Column, sticky=W)  # Put label
                ItiVar = DoubleVar(MainWindowRoot)
                iIti = ttk.Entry(MainWindowRightFrame, textvariable=ItiVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mLickDur = ttk.Label(MainWindowRightFrame, text='LickDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                LickDurVar = DoubleVar(MainWindowRoot)
                iLickDur = ttk.Entry(MainWindowRightFrame, textvariable=LickDurVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label

                Row += 2  # Begin a new line
                Column = 0

                mAutoRewardLatency = ttk.Label(MainWindowRightFrame, text='AutoRewardLat(s)', width=16).grid(row=Row, column=Column, sticky=W)  # Put label
                AutoRewardLatencyVar = DoubleVar(MainWindowRoot)
                iAutoRewardLatency = ttk.Entry(MainWindowRightFrame, textvariable=AutoRewardLatencyVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mMaxAutoRewardNum = ttk.Label(MainWindowRightFrame, text='MaxAutoRewardNum', width=18).grid(row=Row, column=Column, sticky=W)  # Put label
                MaxAutoRewardNumVar = IntVar(MainWindowRoot)
                iMaxAutoRewardNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxAutoRewardNumVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mNextTaskTh = ttk.Label(MainWindowRightFrame, text='NextTaskTh%', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                NextTaskThVar = DoubleVar(MainWindowRoot)
                iNextTaskTh = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskThVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mNextTask = ttk.Label(MainWindowRightFrame, text='NextTask#', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                NextTaskVar = IntVar(MainWindowRoot)
                iNextTask = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label

                Row += 2  # Begin a new line
                Column = 0

                mPanelType = ttk.Label(MainWindowRightFrame, text='PanelType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                PanelTypeVar = StringVar(MainWindowRightFrame)
                tPanelType = OptionMenu(MainWindowRightFrame, PanelTypeVar, "Normal", "Blink", "Textured").grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mWaterCueType = ttk.Label(MainWindowRightFrame, text='WaterCueType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                WaterCueTypeVar = StringVar(MainWindowRightFrame)
                tWaterCueType = OptionMenu(MainWindowRightFrame, WaterCueTypeVar, "Normal", "Blink").grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mPunishWithLight = ttk.Label(MainWindowRightFrame, text='PunishLight', width=11).grid(row=Row, column=Column, sticky=W)  # Put label
                PunishWithLightVar = StringVar(MainWindowRightFrame)
                tPunishWithLight = OptionMenu(MainWindowRightFrame, PunishWithLightVar, "ON", "OFF").grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mAwsOn = ttk.Label(MainWindowRightFrame, text='AWS', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                AwsOnVar = StringVar(MainWindowRoot)
                tAwsOn = OptionMenu(MainWindowRightFrame, AwsOnVar, "ON", "OFF").grid(row=Row + 1, column=Column, sticky=W)  # Put label

                Str = "ParametersForTask" + str(GetTaskID())
                if os.path.exists(Str + '/MaxCorrectNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxCorrectNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxCorrectNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxCorrectNumVar.set(80)  # Default value

                if os.path.exists(Str + '/MaxTrialNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxTrialNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxTrialNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxTrialNumVar.set(110)  # Default value

                if os.path.exists(Str + '/TimeLimit.dat') == True:  # If save file exists
                    with open(Str + '/TimeLimit.dat', 'rb') as PickleInst[GetTaskID()]:
                        TimeLimitVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    TimeLimitVar.set(360)  # Default value

                if os.path.exists(Str + '/PunishDur.dat') == True:  # If save file exists
                    with open(Str + '/PunishDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishDurVar.set(10)  # Default value

                if os.path.exists(Str + '/Iti.dat') == True:  # If save file exists
                    with open(Str + '/Iti.dat', 'rb') as PickleInst[GetTaskID()]:
                        ItiVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    ItiVar.set(1)  # Default value
                if os.path.exists(Str + '/LickDur.dat') == True:  # If save file exists
                    with open(Str + '/LickDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        LickDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    LickDurVar.set(2)  # Default value

                if os.path.exists(Str + '/AutoRewardLatency.dat') == True:  # If save file exists
                    with open(Str + '/AutoRewardLatency.dat', 'rb') as PickleInst[GetTaskID()]:
                        AutoRewardLatencyVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    AutoRewardLatencyVar.set(360)  # Default value

                if os.path.exists(Str + '/MaxAutoRewardNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxAutoRewardNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxAutoRewardNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxAutoRewardNumVar.set(5)  # Default value

                if os.path.exists(Str + '/NextTaskTh.dat') == True:  # If save file exists
                    with open(Str + '/NextTaskTh.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskThVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskThVar.set(50)  # Default value
                if os.path.exists(Str + '/NextTask.dat') == True:  # If save file exists
                    with open(Str + '/NextTask.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskVar.set(2)  # Default value
                if os.path.exists(Str + '/PanelType.dat') == True:  # If save file exists
                    with open(Str + '/PanelType.dat', 'rb') as PickleInst[GetTaskID()]:
                        PanelTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PanelTypeVar.set('Normal')  # Default value

                if os.path.exists(Str + '/WaterCueType.dat') == True:  # If save file exists
                    with open(Str + '/WaterCueType.dat', 'rb') as PickleInst[GetTaskID()]:
                        WaterCueTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    WaterCueTypeVar.set('Blink')  # Default value

                if os.path.exists(Str + '/PunishWithLight.dat') == True:  # If save file exists
                    with open(Str + '/PunishWithLight.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishWithLightVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishWithLightVar.set('ON')  # Default value
                if os.path.exists(Str + '/AwsOn.dat') == True:  # If save file exists
                    with open(Str + '/AwsOn.dat', 'rb') as PickleInst[GetTaskID()]:
                        AwsOnVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    AwsOnVar.set('ON')  # Default value


                RemoveAllRoiGui()
                for i in range(GetCurrentPanelNum()):
                    PutRoiGui(i, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)  Set panel ROIs
                PutRoiGui(19, 0, 0, 1)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)  ROI 19 is water ROI

                RemoveAllDigitalOutGui()
                PutDigitalOutGui(10)  # Cue LED
                PutDigitalOutGui(12)  # IR LED
                PutDigitalOutGui(13)  # Roof LED

                RemoveAllServoGui()
                PutServoGui(3)

                Phase0_Init = 1

        if GetSaveTrgStat() == 1:    # If save trigger is on
            # Parameters of each task are saved into different folder
            Str="ParametersForTask"+str(GetTaskID())   # Path to the folder for saving of parameters
            if os.path.exists(Str) == False:    # If folder for saving parameters is not exist
                os.mkdir(Str)   # Make folder for saving
            with open(Str+'/MaxCorrectNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxCorrectNumVar.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/MaxTrialNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxTrialNumVar.get(),PickleInst[GetTaskID()])     # Save
            with open(Str + '/TimeLimit.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TimeLimitVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str+'/PunishDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishDurVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/Iti.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(ItiVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/LickDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(LickDurVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/AutoRewardLatency.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(AutoRewardLatencyVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/MaxAutoRewardNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxAutoRewardNumVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str + '/NextTask.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str+'/NextTaskTh.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskThVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/PanelType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PanelTypeVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/WaterCueType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(WaterCueTypeVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/PunishWithLight.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishWithLightVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/AwsOn.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(AwsOnVar.get(), PickleInst[GetTaskID()])     # Save

        if Phase == 1:  # Wait for starting of task
            if Phase1_Init == 0:
                PutPreTaskButton()
                mStatusVar = StringVar(MainWindowRoot)
                mStatus = ttk.Label(MainWindowRightFrame, textvariable=mStatusVar)
                mStatus.place(x=10, y=0)
                mOngoingResultVar = StringVar(MainWindowRoot)
                Phase1_Init = 1
            mStatusVar.set('Touch lit panel task (' + str(GetTaskID()) + ')    Waiting...')
            if IsStartTime() == 1:
                StartNow()
        if Phase == 2:  # During task
            if Phase2_Init == 0: # Initialization of the task
                PutEndTaskNowButton()
                mStatusVar.set('Touch lit panel task (' + str(GetTaskID()) + ')    Start time ' + str(TaskStartedMonth) + '/' + str(TaskStartedDay) + ' ' + str(TaskStartedHour) + ':' + str(TaskStartedMinute) + '    Running')
                mOngoingResult = ttk.Label(MainWindowRightFrame, textvariable=mOngoingResultVar)
                mOngoingResult.place(x=10, y=18)

                # Convert StringVars of parameters into integer or normal string to use in the following
                MaxCorrectNum=int(MaxCorrectNumVar.get())
                MaxTrialNum = int(MaxTrialNumVar.get())
                TimeLimit = float(TimeLimitVar.get())
                PunishDur = float(PunishDurVar.get())
                Iti = float(ItiVar.get())
                LickDur = float(LickDurVar.get())
                AutoRewardLatency = float(AutoRewardLatencyVar.get())
                MaxAutoRewardNum = int(MaxAutoRewardNumVar.get())
                NextTask = int(NextTaskVar.get())
                NextTaskTh = float(NextTaskThVar.get())
                PanelType = PanelTypeVar.get()
                WaterCueType =WaterCueTypeVar.get()
                PunishWithLight = PunishWithLightVar.get()
                AwsOn = AwsOnVar.get()

                StartLickRecording()
                RoofLightOff()
                InfraredLightOn()
                if WaterCueType == 'Normal':
                    DigitalOutOn(10)
                if WaterCueType == 'Blink':
                    DigitalOutBlinkOn(10)
                ServoPosInside(3)
                if PanelType=='Normal':
                    CreateNormalPanel_All() #
                if PanelType=='Blink':
                    CreateBlinkPanel_All()
                if PanelType=='Textured':
                    CreateTexturedPanel_All(0)


                # Declar local variables for this task
                TotalTouchNum = 0
                CorrectNum = 0
                IncorrectNum = 0
                CorrectRate = 0
                AutoRewardNum = 0
                RewardNum = 0 # Total number of reward
                TaskDur = 0

                AWS_Latency = 20
                LightCycleControlOff()
                NowDrinking = 0
                CorrectPanelID = 0    # ID of correct panel
                StartRecording()    # Start camera capturing and sending of TTL

                TrialNum=0
                Timer_Start(5)  # Task time limit timer start
                Phase2 = 2
                Phase2_Init = 1

                Writer_TouchEventTxt = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.txt",'w')  # Initialize the text exporter
                Writer_TouchEventCsv = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.csv",'w')  # Initialize the text exporter
                Writer_TouchEventTxt.write('TrialNum\tResult\t\t\tyyyy/mm/dd\th:m\ts\n')  # Write item name
                print("Task #" + str(GetTaskID()) + " is started at " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

            if Phase2 == 0:   # Initiation of new trial
                TaskDur = Timer_GetSec(5)
                TrialNum += 1   #
                CorrectPanelID=int(random.random()*GetCurrentPanelNum())
                print('CorrectPanelID: '+str(CorrectPanelID))
                ShowPanel(CorrectPanelID)
                #ShowPanel(0)
                Timer_Start(0)  # Start the latency timer
                Timer_Start(1)  # Start timer for auto reward
                Phase2 += 1
            if Phase2 == 1:   # Panel presentation
                TouchedPanelID = DetectRoiNosepoke() # Examine which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID != -1 and TouchedPanelID != 19:    # If any panel is touched
                    if TouchedPanelID == int(CorrectPanelID): # If mouse touchs correct panel
                        ServoPosInside(3)  # Move water nozzle to the inside position
                        NowDrinking = 0
                        CorrectNum += 1  # Increase the number of correct respon
                        TotalTouchNum+=1
                        mOngoingResultVar.set('CorrectNum:'+str(CorrectNum)+'  IncorrectNum:'+str(IncorrectNum)+'  TotalNum:'+str(TotalTouchNum)+'  Correct:'+str(round(CorrectNum*100.0/TotalTouchNum, 2))+'%  AutoRewardNum:'+str(AutoRewardNum))
                        Writer_TouchEventTxt.write(str(TrialNum) + '\tPanelTouched(Correct)\t' +str(TouchedPanelID)+'\t'+ str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',1,' +str(TouchedPanelID)+','+ str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the csv file
                        HideAllPanel()
                        Timer_End(0)
                        if WaterCueType == 'Normal':
                            DigitalOutOn(10)
                        if WaterCueType == 'Blink':
                            DigitalOutBlinkOn(10)
                        Phase2 = 2  # Start reward phase
                    if TouchedPanelID != int(CorrectPanelID): # If mouse touchs wrong panel
                        ServoPosOutside(3)
                        if PunishWithLight == 'ON':
                            RoofLightOn()  # Turn on roof light
                        IncorrectNum += 1
                        TotalTouchNum += 1
                        mOngoingResultVar.set('CorrectNum:' + str(CorrectNum) + '  IncorrectNum:' + str(IncorrectNum) + '  TotalNum:' + str(TotalTouchNum) + '  Correct:' + str(round(CorrectNum * 100.0 / TotalTouchNum, 2))+'%  AutoRewardNum:'+str(AutoRewardNum))
                        Writer_TouchEventTxt.write(str(TrialNum) + '\tPanelTouched(Wrong)\t' +str(TouchedPanelID)+'\t'+ str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',0,' +str(TouchedPanelID)+','+ str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the csv file
                        HideAllPanel()
                        Timer_End(0)  # End timer1
                        Timer_Start(0)  # Start punish timer
                        Phase2 = 5  # Start punishment phase
                if AutoRewardNum < MaxAutoRewardNum:
                    if Timer_GetSec(1) >= AutoRewardLatency:   # If time limit is auto reward latency
                        Timer_End(1)
                        ServoPosInside(3)  # Move water nozzle to the inside position
                        if WaterCueType == 'Normal':
                            DigitalOutOn(10)
                        if WaterCueType == 'Blink':
                            DigitalOutBlinkOn(10)
                        NowDrinking = 0
                        AutoRewardNum += 1  # Increase the number of auto reward num
                        if TotalTouchNum > 0:
                            mOngoingResultVar.set('CorrectNum:' + str(CorrectNum) + '  IncorrectNum:' + str(IncorrectNum) + '  TotalNum:' + str(TotalTouchNum) + '  Correct:' + str(round(CorrectNum * 100.0 / TotalTouchNum, 2)) + '%  AutoRewardNum:'+str(AutoRewardNum))
                        Writer_TouchEventTxt.write(str(TrialNum) + '\tAutoRewardSupply\t\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',2,,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                        HideAllPanel()
                        Phase2 = 2
                if Timer_GetSec(5) >= TimeLimit * 60:   # If time limit is exceeded
                    TaskDur = Timer_GetSec(5)
                    Timer_End(5)
                    Phase2 = 6
            if Phase2 == 2:  # Reward phase
                if DetectRoiNosepoke() == 19 and NowDrinking == 0:    # If the mouse initiates nose poke
                    NowDrinking = 1
                    Timer_Start(0)  # Start lick timer
                if NowDrinking == 1:
                    if Timer_GetSec(0) >= LickDur:   # If lick time exceed the designated time
                        Timer_End(0) # End lick timer
                        ServoPosMiddle(3)    # Move water nozzle to the intermediate position
                        DigitalOutOff(10)
                        NowDrinking = 0
                        Timer_Start(0)  # Start ITI timer
                        Phase2 = 3

            if Phase2 == 3:   # ITI
                RewardNum = CorrectNum + AutoRewardNum
                if Timer_GetSec(0) >= Iti:  # If ITI is passed
                    Timer_End(0)
                    Phase2 = 0  # Go to the next trial
                if RewardNum >= MaxCorrectNum or TotalTouchNum >= MaxTrialNum: # If mouse achieved criteria of finishing the task
                    Timer_End(5)
                    ServoPosMiddle(3)
                    DigitalOutOff(10)
                    Timer_Start(0)  # Timer for interval between task and arbitary water supply is started
                    Phase2 = 6  # Go to the AWS
            if Phase2 == 5:   # Punishment phase
                if Timer_GetSec(0) >= PunishDur:    # If punishment time is passed
                    RoofLightOff()
                    ServoPosMiddle(3)    # Move water nozzle to the intermediate position
                    Timer_End(0)  # End punishment timer1
                    Timer_Start(0)  # Start ITI timer
                    Phase2 = 3
            if Phase2==6:
                HideAllPanel()
                if CorrectNum < MaxCorrectNum and AwsOn=='ON':  # If mouse didn't achieved the max correct response
                    Timer_Start(0)
                    Phase2 = 7
                if CorrectNum == MaxCorrectNum or AwsOn=='OFF':  # If mouse achieved the max correct response
                    Phase2 = -1
            if Phase2==7:   # Wait until arbitary water suuply is started
                if Timer_GetSec(0) >= AWS_Latency:   # If the interval is past 60
                    Timer_End(0)
                    ArbitaryWaterSupplyDur=(MaxCorrectNum - CorrectNum) * LickDur * 1000    # Caliculate duration of complement water supply
                    if WaterCueType == 'Normal':
                        StartArbitaryWaterSupply(3,10,0,ArbitaryWaterSupplyDur) # Start complement water supply
                    if WaterCueType == 'Blink':
                        StartArbitaryWaterSupply(3,10,1,ArbitaryWaterSupplyDur) # Start complement water supply
                    print("AWSstart")
                    Phase2=8
            if Phase2==8:
                if GetArbitaryWaterSupplyStat()==1: # If complement water supply is finished
                    Phase2 = -1

            if Phase2 == -1 or GetEndTaskNowButtonStat() == 1:  # Task finish phase
                LightCycleControlOn()
                ServoPosMiddle(3)
                DeleteAllPanel()
                InfraredLightOff()
                if GetRecordingStat() == 1:
                    SetEndRecordingTimer(60)
                if CorrectNum > 0 or IncorrectNum > 0:
                    CorrectRate = int(CorrectNum * 100.0 / TotalTouchNum)
                    Writer_TouchEventTxt.write('TotalNum:'+str(TotalTouchNum)+'  Correct num:'+str(CorrectNum)+'  Incorrect num:'+str(IncorrectNum)+'  Correct rate:'+str(CorrectRate)+'%  Auto reward num:'+str(AutoRewardNum)+'\n')   #結果テキストの一番最後に成績のまとめを記入
                Writer_TouchEventTxt.write('SessionStartTime: ' + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()) + "\n")
                Writer_TouchEventTxt.write('SessionEndTime: ' + str(TimeNow.month) + '/' + str(TimeNow.day) + ' ' + str(TimeNow.hour) + ':' + str(TimeNow.minute) + ':' + str(TimeNow.second + (TimeNow.microsecond // 1000) / 1000) + "\n")
                Writer_TouchEventTxt.write('TaskDuration(sec): ' + str(TaskDur) + "\n")
                Writer_TouchEventTxt.write('MaxCorrectNum: '+str(MaxCorrectNum)+"\n")
                Writer_TouchEventTxt.write('MaxTrialNum: ' + str(MaxTrialNum) + "\n")
                Writer_TouchEventTxt.write('TimeLimit: ' + str(TimeLimit) + "\n")
                Writer_TouchEventTxt.write('PunishDur: ' + str(PunishDur) + "\n")
                Writer_TouchEventTxt.write('Iti: ' + str(Iti) + "\n")
                Writer_TouchEventTxt.write('LickDur: ' + str(LickDur) + "\n")
                Writer_TouchEventTxt.write('AutoRewardLatency: ' + str(AutoRewardLatency) + "\n")
                Writer_TouchEventTxt.write('MaxAutoRewardNum: ' + str(AutoRewardNum) + "\n")
                Writer_TouchEventTxt.write('NextTask: ' + str(NextTask) + "\n")
                Writer_TouchEventTxt.write('NextTaskTh: ' + str(NextTaskTh)+"\n")
                Writer_TouchEventTxt.write('PanelType: ' + str(PanelType) + "\n")
                Writer_TouchEventTxt.write('WaterCueType: ' + str(WaterCueType) + "\n")
                Writer_TouchEventTxt.write('PunishLight: ' + str(PunishWithLight)+"\n")
                Writer_TouchEventTxt.write('RecordFPS: ' + str(GetRecordFps()) + "\n")
                Writer_TouchEventTxt.write('AWS: ' + AwsOn + "\n")
                Writer_TouchEventTxt.write('AWS_Latency: ' + str(AWS_Latency) + "\n")
                Writer_TouchEventTxt.write(GetRoiSensitivity() + "\n")
                Writer_TouchEventTxt.write(GetServoAngle() + "\n")
                Writer_TouchEventTxt.close()
                Writer_TouchEventCsv.close()
                EndLickRecording()

                SendMail(DeviceNameVar.get() + ' finished task '+str(GetTaskID())+'. Correct:' + str(CorrectNum) + ' Incorrect:' + str(IncorrectNum) + ' Correct:'+str(CorrectRate)+'% Dur:' + str(round(Timer_GetSec(5) / 60,1)) + ' min', 'The task is finished.')

                if IsHousingAnalysis == 1 and Phase2 == -1:  # If it is housing analysis
                    if CorrectRate >= NextTaskTh:   # If the score exceed the criteria to switch the next task
                        SwitchTask(NextTask) # Onset task switch trigger
                        print("Task is switched to task#"+str(NextTask)+"  "+str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

                if IsHousingAnalysis == 0:
                    RoofLightOn()
                Phase = 1  # Go back to the task-waiting phase
                Phase2 = 0
                Phase2_Init = 0
            SetDispVariable(0, 'Phase2', str(Phase2))  # Display "Phase2" value on the main window
    return

def Task3():   # Touch lit panel task
    global Phase
    Phase0_Init=0
    Phase1_Init=0
    Phase2_Init=0
    while EndFlag==0:
        OperantHouseUpdate()
        if GetBackButtonStat()==1:    # If "Back" button is clicked
            break   # Back to the task select phase
        if Phase == 0:  # Parameter inputs
            if Phase0_Init == 0:
                # Make GUI for the setting of the parameters for this task
                RemoveMainRightWidget() # Remove task buttons
                PutStartBackButton()    # Put start/back buttons

                ColumnWidth = 14
                Row = 0  # Begin a new line
                Column = 0
                mMaxCorrectNum = ttk.Label(MainWindowRightFrame, text='MaxCorrectNum', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                MaxCorrectNumVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iMaxCorrectNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxCorrectNumVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mMaxTrialNum = ttk.Label(MainWindowRightFrame, text='MaxTrialNum', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                MaxTrialNumVar = IntVar(MainWindowRoot)
                iMaxTrialNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxTrialNumVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mTimeLimit = ttk.Label(MainWindowRightFrame, text='TimeLimit(min)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                TimeLimitVar = DoubleVar(MainWindowRoot)
                iTimeLimit = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mPunishDur = ttk.Label(MainWindowRightFrame, text='PunishDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                PunishDurVar = DoubleVar(MainWindowRoot)
                iPunishDur = ttk.Entry(MainWindowRightFrame, textvariable=PunishDurVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mIti = ttk.Label(MainWindowRightFrame, text='ITI(s)', width=11).grid(row=Row, column=Column, sticky=W)  # Put label
                ItiVar = DoubleVar(MainWindowRoot)
                iIti = ttk.Entry(MainWindowRightFrame, textvariable=ItiVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mLickDur = ttk.Label(MainWindowRightFrame, text='LickDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                LickDurVar = DoubleVar(MainWindowRoot)
                iLickDur = ttk.Entry(MainWindowRightFrame, textvariable=LickDurVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label

                Row += 2  # Begin a new line
                Column = 0

                mAutoRewardLatency = ttk.Label(MainWindowRightFrame, text='AutoRewardLat(s)', width=16).grid(row=Row, column=Column, sticky=W)  # Put label
                AutoRewardLatencyVar = DoubleVar(MainWindowRoot)
                iAutoRewardLatency = ttk.Entry(MainWindowRightFrame, textvariable=AutoRewardLatencyVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mMaxAutoRewardNum = ttk.Label(MainWindowRightFrame, text='MaxAutoRewardNum', width=18).grid(row=Row, column=Column, sticky=W)  # Put label
                MaxAutoRewardNumVar = IntVar(MainWindowRoot)
                iMaxAutoRewardNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxAutoRewardNumVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mNextTaskTh = ttk.Label(MainWindowRightFrame, text='NextTaskTh%', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                NextTaskThVar = DoubleVar(MainWindowRoot)
                iNextTaskTh = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskThVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mNextTask = ttk.Label(MainWindowRightFrame, text='NextTask#', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                NextTaskVar = IntVar(MainWindowRoot)
                iNextTask = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label

                Row += 2  # Begin a new line
                Column = 0

                mPanelType = ttk.Label(MainWindowRightFrame, text='PanelType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                PanelTypeVar = StringVar(MainWindowRightFrame)
                tPanelType = OptionMenu(MainWindowRightFrame, PanelTypeVar, "Normal", "Blink", "Textured").grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mWaterCueType = ttk.Label(MainWindowRightFrame, text='WaterCueType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                WaterCueTypeVar = StringVar(MainWindowRightFrame)
                tWaterCueType = OptionMenu(MainWindowRightFrame, WaterCueTypeVar, "Normal", "Blink").grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mPunishWithLight = ttk.Label(MainWindowRightFrame, text='PunishLight', width=11).grid(row=Row, column=Column, sticky=W)  # Put label
                PunishWithLightVar = StringVar(MainWindowRightFrame)
                tPunishWithLight = OptionMenu(MainWindowRightFrame, PunishWithLightVar, "ON", "OFF").grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mAwsOn = ttk.Label(MainWindowRightFrame, text='AWS', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                AwsOnVar = StringVar(MainWindowRoot)
                tAwsOn = OptionMenu(MainWindowRightFrame, AwsOnVar, "ON", "OFF").grid(row=Row + 1, column=Column, sticky=W)  # Put label

                Str = "ParametersForTask" + str(GetTaskID())
                if os.path.exists(Str + '/MaxCorrectNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxCorrectNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxCorrectNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxCorrectNumVar.set(80)  # Default value

                if os.path.exists(Str + '/MaxTrialNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxTrialNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxTrialNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxTrialNumVar.set(110)  # Default value

                if os.path.exists(Str + '/TimeLimit.dat') == True:  # If save file exists
                    with open(Str + '/TimeLimit.dat', 'rb') as PickleInst[GetTaskID()]:
                        TimeLimitVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    TimeLimitVar.set(360)  # Default value

                if os.path.exists(Str + '/PunishDur.dat') == True:  # If save file exists
                    with open(Str + '/PunishDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishDurVar.set(10)  # Default value

                if os.path.exists(Str + '/Iti.dat') == True:  # If save file exists
                    with open(Str + '/Iti.dat', 'rb') as PickleInst[GetTaskID()]:
                        ItiVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    ItiVar.set(1)  # Default value
                if os.path.exists(Str + '/LickDur.dat') == True:  # If save file exists
                    with open(Str + '/LickDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        LickDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    LickDurVar.set(2)  # Default value

                if os.path.exists(Str + '/AutoRewardLatency.dat') == True:  # If save file exists
                    with open(Str + '/AutoRewardLatency.dat', 'rb') as PickleInst[GetTaskID()]:
                        AutoRewardLatencyVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    AutoRewardLatencyVar.set(360)  # Default value

                if os.path.exists(Str + '/MaxAutoRewardNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxAutoRewardNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxAutoRewardNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxAutoRewardNumVar.set(5)  # Default value

                if os.path.exists(Str + '/NextTaskTh.dat') == True:  # If save file exists
                    with open(Str + '/NextTaskTh.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskThVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskThVar.set(50)  # Default value
                if os.path.exists(Str + '/NextTask.dat') == True:  # If save file exists
                    with open(Str + '/NextTask.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskVar.set(2)  # Default value
                if os.path.exists(Str + '/PanelType.dat') == True:  # If save file exists
                    with open(Str + '/PanelType.dat', 'rb') as PickleInst[GetTaskID()]:
                        PanelTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PanelTypeVar.set('Normal')  # Default value

                if os.path.exists(Str + '/WaterCueType.dat') == True:  # If save file exists
                    with open(Str + '/WaterCueType.dat', 'rb') as PickleInst[GetTaskID()]:
                        WaterCueTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    WaterCueTypeVar.set('Blink')  # Default value

                if os.path.exists(Str + '/PunishWithLight.dat') == True:  # If save file exists
                    with open(Str + '/PunishWithLight.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishWithLightVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishWithLightVar.set('ON')  # Default value
                if os.path.exists(Str + '/AwsOn.dat') == True:  # If save file exists
                    with open(Str + '/AwsOn.dat', 'rb') as PickleInst[GetTaskID()]:
                        AwsOnVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    AwsOnVar.set('ON')  # Default value


                RemoveAllRoiGui()
                for i in range(GetCurrentPanelNum()):
                    PutRoiGui(i, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)  Set panel ROIs
                PutRoiGui(19, 0, 0, 1)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)  ROI 19 is water ROI

                RemoveAllDigitalOutGui()
                PutDigitalOutGui(10)  # Cue LED
                PutDigitalOutGui(12)  # IR LED
                PutDigitalOutGui(13)  # Roof LED

                RemoveAllServoGui()
                PutServoGui(3)

                Phase0_Init = 1

        if GetSaveTrgStat() == 1:    # If save trigger is on
            # Parameters of each task are saved into different folder
            Str="ParametersForTask"+str(GetTaskID())   # Path to the folder for saving of parameters
            if os.path.exists(Str) == False:    # If folder for saving parameters is not exist
                os.mkdir(Str)   # Make folder for saving
            with open(Str+'/MaxCorrectNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxCorrectNumVar.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/MaxTrialNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxTrialNumVar.get(),PickleInst[GetTaskID()])     # Save
            with open(Str + '/TimeLimit.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TimeLimitVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str+'/PunishDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishDurVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/Iti.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(ItiVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/LickDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(LickDurVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/AutoRewardLatency.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(AutoRewardLatencyVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/MaxAutoRewardNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxAutoRewardNumVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str + '/NextTask.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str+'/NextTaskTh.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskThVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/PanelType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PanelTypeVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/WaterCueType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(WaterCueTypeVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/PunishWithLight.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishWithLightVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/AwsOn.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(AwsOnVar.get(), PickleInst[GetTaskID()])     # Save

        if Phase == 1:  # Wait for starting of task
            if Phase1_Init == 0:
                PutPreTaskButton()
                mStatusVar = StringVar(MainWindowRoot)
                mStatus = ttk.Label(MainWindowRightFrame, textvariable=mStatusVar)
                mStatus.place(x=10, y=0)
                mOngoingResultVar = StringVar(MainWindowRoot)
                Phase1_Init = 1
            mStatusVar.set('Touch lit panel task (' + str(GetTaskID()) + ')    Waiting...')
            if IsStartTime() == 1:
                StartNow()
        if Phase == 2:  # During task
            if Phase2_Init == 0: # Initialization of the task
                PutEndTaskNowButton()
                mStatusVar.set('Touch lit panel task (' + str(GetTaskID()) + ')    Start time ' + str(TaskStartedMonth) + '/' + str(TaskStartedDay) + ' ' + str(TaskStartedHour) + ':' + str(TaskStartedMinute) + '    Running')
                mOngoingResult = ttk.Label(MainWindowRightFrame, textvariable=mOngoingResultVar)
                mOngoingResult.place(x=10, y=18)

                # Convert StringVars of parameters into integer or normal string to use in the following
                MaxCorrectNum=int(MaxCorrectNumVar.get())
                MaxTrialNum = int(MaxTrialNumVar.get())
                TimeLimit = float(TimeLimitVar.get())
                PunishDur = float(PunishDurVar.get())
                Iti = float(ItiVar.get())
                LickDur = float(LickDurVar.get())
                AutoRewardLatency = float(AutoRewardLatencyVar.get())
                MaxAutoRewardNum = int(MaxAutoRewardNumVar.get())
                NextTask = int(NextTaskVar.get())
                NextTaskTh = float(NextTaskThVar.get())
                PanelType = PanelTypeVar.get()
                WaterCueType =WaterCueTypeVar.get()
                PunishWithLight = PunishWithLightVar.get()
                AwsOn = AwsOnVar.get()

                StartLickRecording()
                RoofLightOff()
                InfraredLightOn()
                if WaterCueType == 'Normal':
                    DigitalOutOn(10)
                if WaterCueType == 'Blink':
                    DigitalOutBlinkOn(10)
                ServoPosInside(3)
                if PanelType=='Normal':
                    CreateNormalPanel_All() #
                if PanelType=='Blink':
                    CreateBlinkPanel_All()
                if PanelType=='Textured':
                    CreateTexturedPanel_All(0)


                # Declar local variables for this task
                TotalTouchNum = 0
                CorrectNum = 0
                IncorrectNum = 0
                CorrectRate = 0
                AutoRewardNum = 0
                RewardNum = 0 # Total number of reward
                TaskDur = 0

                AWS_Latency = 20
                LightCycleControlOff()
                NowDrinking = 0
                CorrectPanelID = 0    # ID of correct panel
                StartRecording()    # Start camera capturing and sending of TTL

                TrialNum=0
                Timer_Start(5)  # Task time limit timer start
                Phase2 = 2
                Phase2_Init = 1

                Writer_TouchEventTxt = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.txt",'w')  # Initialize the text exporter
                Writer_TouchEventCsv = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.csv",'w')  # Initialize the text exporter
                Writer_TouchEventTxt.write('TrialNum\tResult\t\t\tyyyy/mm/dd\th:m\ts\n')  # Write item name
                print("Task #" + str(GetTaskID()) + " is started at " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

            if Phase2 == 0:   # Initiation of new trial
                TaskDur = Timer_GetSec(5)
                TrialNum += 1   #
                CorrectPanelID=int(random.random()*GetCurrentPanelNum())
                print('CorrectPanelID: '+str(CorrectPanelID))
                ShowPanel(CorrectPanelID)
                #ShowPanel(0)
                Timer_Start(0)  # Start the latency timer
                Timer_Start(1)  # Start timer for auto reward
                Phase2 += 1
            if Phase2 == 1:   # Panel presentation
                TouchedPanelID = DetectRoiNosepoke() # Examine which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID != -1 and TouchedPanelID != 19:    # If any panel is touched
                    if TouchedPanelID == int(CorrectPanelID): # If mouse touchs correct panel
                        ServoPosInside(3)  # Move water nozzle to the inside position
                        NowDrinking = 0
                        CorrectNum += 1  # Increase the number of correct respon
                        TotalTouchNum+=1
                        mOngoingResultVar.set('CorrectNum:'+str(CorrectNum)+'  IncorrectNum:'+str(IncorrectNum)+'  TotalNum:'+str(TotalTouchNum)+'  Correct:'+str(round(CorrectNum*100.0/TotalTouchNum, 2))+'%  AutoRewardNum:'+str(AutoRewardNum))
                        Writer_TouchEventTxt.write(str(TrialNum) + '\tPanelTouched(Correct)\t' +str(TouchedPanelID)+'\t'+ str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',1,' +str(TouchedPanelID)+','+ str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the csv file
                        HideAllPanel()
                        Timer_End(0)
                        if WaterCueType == 'Normal':
                            DigitalOutOn(10)
                        if WaterCueType == 'Blink':
                            DigitalOutBlinkOn(10)
                        Phase2 = 2  # Start reward phase
                    if TouchedPanelID != int(CorrectPanelID): # If mouse touchs wrong panel
                        ServoPosOutside(3)
                        if PunishWithLight == 'ON':
                            RoofLightOn()  # Turn on roof light
                        IncorrectNum += 1
                        TotalTouchNum += 1
                        mOngoingResultVar.set('CorrectNum:' + str(CorrectNum) + '  IncorrectNum:' + str(IncorrectNum) + '  TotalNum:' + str(TotalTouchNum) + '  Correct:' + str(round(CorrectNum * 100.0 / TotalTouchNum, 2))+'%  AutoRewardNum:'+str(AutoRewardNum))
                        Writer_TouchEventTxt.write(str(TrialNum) + '\tPanelTouched(Wrong)\t' +str(TouchedPanelID)+'\t'+ str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',0,' +str(TouchedPanelID)+','+ str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the csv file
                        HideAllPanel()
                        Timer_End(0)  # End timer1
                        Timer_Start(0)  # Start punish timer
                        Phase2 = 5  # Start punishment phase
                if AutoRewardNum < MaxAutoRewardNum:
                    if Timer_GetSec(1) >= AutoRewardLatency:   # If time limit is auto reward latency
                        Timer_End(1)
                        ServoPosInside(3)  # Move water nozzle to the inside position
                        if WaterCueType == 'Normal':
                            DigitalOutOn(10)
                        if WaterCueType == 'Blink':
                            DigitalOutBlinkOn(10)
                        NowDrinking = 0
                        AutoRewardNum += 1  # Increase the number of auto reward num
                        if TotalTouchNum > 0:
                            mOngoingResultVar.set('CorrectNum:' + str(CorrectNum) + '  IncorrectNum:' + str(IncorrectNum) + '  TotalNum:' + str(TotalTouchNum) + '  Correct:' + str(round(CorrectNum * 100.0 / TotalTouchNum, 2)) + '%  AutoRewardNum:'+str(AutoRewardNum))
                        Writer_TouchEventTxt.write(str(TrialNum) + '\tAutoRewardSupply\t\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',2,,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                        HideAllPanel()
                        Phase2 = 2
                if Timer_GetSec(5) >= TimeLimit * 60:   # If time limit is exceeded
                    TaskDur = Timer_GetSec(5)
                    Timer_End(5)
                    Phase2 = 6
            if Phase2 == 2:  # Reward phase
                if DetectRoiNosepoke() == 19 and NowDrinking == 0:    # If the mouse initiates nose poke
                    NowDrinking = 1
                    Timer_Start(0)  # Start lick timer
                if NowDrinking == 1:
                    if Timer_GetSec(0) >= LickDur:   # If lick time exceed the designated time
                        Timer_End(0) # End lick timer
                        ServoPosMiddle(3)    # Move water nozzle to the intermediate position
                        DigitalOutOff(10)
                        NowDrinking = 0
                        Timer_Start(0)  # Start ITI timer
                        Phase2 = 3

            if Phase2 == 3:   # ITI
                RewardNum = CorrectNum + AutoRewardNum
                if Timer_GetSec(0) >= Iti:  # If ITI is passed
                    Timer_End(0)
                    Phase2 = 0  # Go to the next trial
                if RewardNum >= MaxCorrectNum or TotalTouchNum >= MaxTrialNum: # If mouse achieved criteria of finishing the task
                    Timer_End(5)
                    ServoPosMiddle(3)
                    DigitalOutOff(10)
                    Timer_Start(0)  # Timer for interval between task and arbitary water supply is started
                    Phase2 = 6  # Go to the AWS
            if Phase2 == 5:   # Punishment phase
                if Timer_GetSec(0) >= PunishDur:    # If punishment time is passed
                    RoofLightOff()
                    ServoPosMiddle(3)    # Move water nozzle to the intermediate position
                    Timer_End(0)  # End punishment timer1
                    Timer_Start(0)  # Start ITI timer
                    Phase2 = 3
            if Phase2==6:
                HideAllPanel()
                if CorrectNum < MaxCorrectNum and AwsOn=='ON':  # If mouse didn't achieved the max correct response
                    Timer_Start(0)
                    Phase2 = 7
                if CorrectNum == MaxCorrectNum or AwsOn=='OFF':  # If mouse achieved the max correct response
                    Phase2 = -1
            if Phase2==7:   # Wait until arbitary water suuply is started
                if Timer_GetSec(0) >= AWS_Latency:   # If the interval is past 60
                    Timer_End(0)
                    ArbitaryWaterSupplyDur=(MaxCorrectNum - CorrectNum) * LickDur * 1000    # Caliculate duration of complement water supply
                    if WaterCueType == 'Normal':
                        StartArbitaryWaterSupply(3,10,0,ArbitaryWaterSupplyDur) # Start complement water supply
                    if WaterCueType == 'Blink':
                        StartArbitaryWaterSupply(3,10,1,ArbitaryWaterSupplyDur) # Start complement water supply
                    print("AWSstart")
                    Phase2=8
            if Phase2==8:
                if GetArbitaryWaterSupplyStat()==1: # If complement water supply is finished
                    Phase2 = -1

            if Phase2 == -1 or GetEndTaskNowButtonStat() == 1:  # Task finish phase
                LightCycleControlOn()
                ServoPosMiddle(3)
                DeleteAllPanel()
                InfraredLightOff()
                if GetRecordingStat() == 1:
                    SetEndRecordingTimer(60)
                if CorrectNum > 0 or IncorrectNum > 0:
                    CorrectRate = int(CorrectNum * 100.0 / TotalTouchNum)
                    Writer_TouchEventTxt.write('TotalNum:'+str(TotalTouchNum)+'  Correct num:'+str(CorrectNum)+'  Incorrect num:'+str(IncorrectNum)+'  Correct rate:'+str(CorrectRate)+'%  Auto reward num:'+str(AutoRewardNum)+'\n')   #結果テキストの一番最後に成績のまとめを記入
                Writer_TouchEventTxt.write('SessionStartTime: ' + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()) + "\n")
                Writer_TouchEventTxt.write('SessionEndTime: ' + str(TimeNow.month) + '/' + str(TimeNow.day) + ' ' + str(TimeNow.hour) + ':' + str(TimeNow.minute) + ':' + str(TimeNow.second + (TimeNow.microsecond // 1000) / 1000) + "\n")
                Writer_TouchEventTxt.write('TaskDuration(sec): ' + str(TaskDur) + "\n")
                Writer_TouchEventTxt.write('MaxCorrectNum: '+str(MaxCorrectNum)+"\n")
                Writer_TouchEventTxt.write('MaxTrialNum: ' + str(MaxTrialNum) + "\n")
                Writer_TouchEventTxt.write('TimeLimit: ' + str(TimeLimit) + "\n")
                Writer_TouchEventTxt.write('PunishDur: ' + str(PunishDur) + "\n")
                Writer_TouchEventTxt.write('Iti: ' + str(Iti) + "\n")
                Writer_TouchEventTxt.write('LickDur: ' + str(LickDur) + "\n")
                Writer_TouchEventTxt.write('AutoRewardLatency: ' + str(AutoRewardLatency) + "\n")
                Writer_TouchEventTxt.write('MaxAutoRewardNum: ' + str(AutoRewardNum) + "\n")
                Writer_TouchEventTxt.write('NextTask: ' + str(NextTask) + "\n")
                Writer_TouchEventTxt.write('NextTaskTh: ' + str(NextTaskTh)+"\n")
                Writer_TouchEventTxt.write('PanelType: ' + str(PanelType) + "\n")
                Writer_TouchEventTxt.write('WaterCueType: ' + str(WaterCueType) + "\n")
                Writer_TouchEventTxt.write('PunishLight: ' + str(PunishWithLight)+"\n")
                Writer_TouchEventTxt.write('RecordFPS: ' + str(GetRecordFps()) + "\n")
                Writer_TouchEventTxt.write('AWS: ' + AwsOn + "\n")
                Writer_TouchEventTxt.write('AWS_Latency: ' + str(AWS_Latency) + "\n")
                Writer_TouchEventTxt.write(GetRoiSensitivity() + "\n")
                Writer_TouchEventTxt.write(GetServoAngle() + "\n")
                Writer_TouchEventTxt.close()
                Writer_TouchEventCsv.close()
                EndLickRecording()

                SendMail(DeviceNameVar.get() + ' finished task '+str(GetTaskID())+'. Correct:' + str(CorrectNum) + ' Incorrect:' + str(IncorrectNum) + ' Correct:'+str(CorrectRate)+'% Dur:' + str(round(Timer_GetSec(5) / 60,1)) + ' min', 'The task is finished.')

                if IsHousingAnalysis == 1 and Phase2 == -1:  # If it is housing analysis
                    if CorrectRate >= NextTaskTh:   # If the score exceed the criteria to switch the next task
                        SwitchTask(NextTask) # Onset task switch trigger
                        print("Task is switched to task#"+str(NextTask)+"  "+str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

                if IsHousingAnalysis == 0:
                    RoofLightOn()
                Phase = 1  # Go back to the task-waiting phase
                Phase2 = 0
                Phase2_Init = 0
            SetDispVariable(0, 'Phase2', str(Phase2))  # Display "Phase2" value on the main window
    return

def Task4():   # Touch all panels task
    global Phase
    Phase0_Init = 0
    Phase1_Init = 0
    Phase2_Init = 0
    while EndFlag == 0:
        OperantHouseUpdate()    # Run house keeping function (This must be executed once per frame)

        if GetBackButtonStat()==1:    # If "Back" button is clicked
            break   # Back to the task select phase
        if Phase == 0:  # Parameter inputs
            if Phase0_Init == 0:    # Make GUI for the setting of the parameters for this task
                RemoveMainRightWidget() # Remove task buttons
                PutStartBackButton()    # Put "start" and "back" buttons

                ColumnWidth = 14    # Width of input columns
                Row = 0
                Column = 0
                mMaxCorrectNum = ttk.Label(MainWindowRightFrame, text='MaxCorrectNum', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                MaxCorrectNumVar = IntVar(MainWindowRoot)  # Declare a variable for input column
                iMaxCorrectNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxCorrectNumVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Create input column and link it with the variable
                Column += 1
                mTimeLimit = ttk.Label(MainWindowRightFrame, text='TimeLimit(min)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                TimeLimitVar = DoubleVar(MainWindowRoot)
                iTimeLimit = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitVar, width=ColumnWidth).grid(row=Row + 1, column=Column)
                Column += 1
                mLickDur = ttk.Label(MainWindowRightFrame, text='LickDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                LickDurVar = DoubleVar(MainWindowRoot)
                iLickDur = ttk.Entry(MainWindowRightFrame, textvariable=LickDurVar, width=ColumnWidth).grid(row=Row + 1, column=Column)
                Column += 1
                mNextTask = ttk.Label(MainWindowRightFrame, text='NextTask#', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # The task number indicated here will be the next task if the correct rate exceeds "NextTaskTh"
                NextTaskVar = IntVar(MainWindowRoot)
                iNextTask = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskVar, width=ColumnWidth).grid(row=Row + 1, column=Column)
                Column += 1
                mNextTaskTh = ttk.Label(MainWindowRightFrame, text='NextTaskTh', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)   # Correct rate threshold to switch to the next task
                NextTaskThVar = DoubleVar(MainWindowRoot)
                iNextTaskTh = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskThVar, width=ColumnWidth).grid(row=Row + 1, column=Column)

                Row += 2  # Begin a new line
                Column = 0

                mWaterCueType = ttk.Label(MainWindowRightFrame, text='WaterCueType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # If chose blink, reward cue will blink
                WaterCueTypeVar = StringVar(MainWindowRightFrame)
                tWaterCueType = OptionMenu(MainWindowRightFrame, WaterCueTypeVar, "Normal", "Blink").grid(row=Row + 1, column=Column, sticky=W)
                Column += 1
                mAwsOn = ttk.Label(MainWindowRightFrame, text='AWS', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # If ON, complemental water supply is applied after end of each session
                AwsOnVar = StringVar(MainWindowRoot)
                tAwsOn = OptionMenu(MainWindowRightFrame, AwsOnVar, "ON", "OFF").grid(row=Row + 1, column=Column, sticky=W)

                Str = "ParametersForTask" + str(GetTaskID())
                if os.path.exists(Str + '/MaxCorrectNum.dat') == True:  # If save file named "MaxCorrectNum.dat" exist:
                    with open(Str + '/MaxCorrectNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxCorrectNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Assign loaded data into the variable of this program
                else:  # If save file doesn't exist
                    MaxCorrectNumVar.set(80)  # Assign 80 into the variable

                if os.path.exists(Str + '/TimeLimit.dat') == True:
                    with open(Str + '/TimeLimit.dat', 'rb') as PickleInst[GetTaskID()]:
                        TimeLimitVar.set(pickle.load(PickleInst[GetTaskID()]))
                else:
                    TimeLimitVar.set(600)

                if os.path.exists(Str + '/LickDur.dat') == True:
                    with open(Str + '/LickDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        LickDurVar.set(pickle.load(PickleInst[GetTaskID()]))
                else:
                    LickDurVar.set(2)

                if os.path.exists(Str + '/NextTask.dat') == True:
                    with open(Str + '/NextTask.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskVar.set(4)  # Default value

                if os.path.exists(Str + '/NextTaskTh.dat') == True:
                    with open(Str + '/NextTaskTh.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskThVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskThVar.set(80)  # Default value

                if os.path.exists(Str + '/WaterCueType.dat') == True:
                    with open(Str + '/WaterCueType.dat', 'rb') as PickleInst[GetTaskID()]:
                        WaterCueTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    WaterCueTypeVar.set('Blink')  # Default value

                if os.path.exists(Str + '/AwsOn.dat') == True:
                    with open(Str + '/AwsOn.dat', 'rb') as PickleInst[GetTaskID()]:
                        AwsOnVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    AwsOnVar.set('ON')  # Default value

                PanelNum = GetCurrentPanelNum()
                RemoveAllRoiGui()
                for i in range(PanelNum):
                    PutRoiGui(i, 1, 1, 0)  # Put setting GUI of the indicated ROI on ROI window (ROI number, Detection mode, Threshold direction, ShowSymbol or not)
                PutRoiGui(19, 0, 0, 1)

                RemoveAllDigitalOutGui()  # Remove all GUIs on the Digital out window
                PutDigitalOutGui(10)  # Put the digital output GUI for channel 10 on Digital ouput window
                PutDigitalOutGui(12)
                PutDigitalOutGui(13)

                RemoveAllServoGui()  # Remove all GUI on the Servo GUI
                PutServoGui(3)  # Put a servo GUI for channel 3 on the Servo GUI

                Phase0_Init = 1 # Set a flag which indicating phase0 initialization has done

        if GetSaveTrgStat() == 1:    # If save trigger is activated
            # Parameters will be saved into a folder named "ParametersForTask90"
            Str="ParametersForTask"+str(GetTaskID())   # Assign save folder path
            if os.path.exists(Str) == False:    # If save folder doesn't exist
                os.mkdir(Str)   # Create the folder
            with open(Str+'/MaxCorrectNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxCorrectNumVar.get(),PickleInst[GetTaskID()])     # Save a value of "MaxCorrectNumVar" as "MaxCorrectNum.dat" file

            with open(Str+'/TimeLimit.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TimeLimitVar.get(),PickleInst[GetTaskID()])

            with open(Str+'/LickDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(LickDurVar.get(), PickleInst[GetTaskID()])

            with open(Str + '/NextTask.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskVar.get(), PickleInst[GetTaskID()])

            with open(Str+'/NextTaskTh.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskThVar.get(), PickleInst[GetTaskID()])

            with open(Str+'/WaterCueType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(WaterCueTypeVar.get(), PickleInst[GetTaskID()])

            with open(Str+'/AwsOn.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(AwsOnVar.get(), PickleInst[GetTaskID()])

        if Phase == 1:  # Waiting phase (Task will start when the set time arrives)
            if Phase1_Init == 0: # If the initialization for phase1 has not done
                PutPreTaskButton()  # Put "StartNow" and "Back" button on Main window
                mStatusVar = StringVar(MainWindowRoot)  # Create a variable for status display
                mStatus = ttk.Label(MainWindowRightFrame, textvariable=mStatusVar)  # Create label object and link it with Main window
                mStatus.place(x=10, y=0)    # Place label object on the Main window
                mOngoingResultVar = StringVar(MainWindowRoot)   # Create a variable for progress display
                Phase1_Init = 1 # Flat that phase1 has done
            mStatusVar.set('Test37 task (' + str(GetTaskID()) + ')    Waiting...')    # Show current status of the Operant House
            if IsStartTime() == 1:  # Check whether task start time arrives
                StartNow()  # Start task (Phase number will be "2")

        if Phase == 2:  # If it is during task
            if Phase2_Init == 0: # Initialization of the task
                PutEndTaskNowButton()   # Put "TaskEnd" button on Main window
                mStatusVar.set('Test4 task (' + str(GetTaskID()) + ')    Start time ' + str(TaskStartedMonth) + '/' + str(TaskStartedDay) + ' ' + str(TaskStartedHour) + ':' + str(TaskStartedMinute) + '    Running')    # Assign latest information about current task into "mStatusVar"
                mOngoingResult = ttk.Label(MainWindowRightFrame, textvariable=mOngoingResultVar)
                mOngoingResult.place(x=10, y=18)

                # Assign task parameter values in StringVars into integer or string variable (to make the cord easeir to read)
                MaxCorrectNum = int(MaxCorrectNumVar.get())   # Get the value of "MaxCorrectNumVar" and convert it from string to integer and assign into variable named "MaxCorrectNum"
                TimeLimit = float(TimeLimitVar.get())
                LickDur = float(LickDurVar.get())
                NextTask = int(NextTaskVar.get())
                NextTaskTh = float(NextTaskThVar.get())
                WaterCueType = WaterCueTypeVar.get()
                AwsOn = AwsOnVar.get()

                # Declar local variables for this task
                TrialNum = 0    # Current trial number
                CorrectNum = 0  # Current correct trial number
                IncorrectNum = 0    # Current incorrect trial number
                CorrectRate = 0.0   # Current correct rate
                TaskDur = 0  # This will keep the elapsed time during of task
                NowDrinking = 0 # Use as trigger
                AWS_Latency = 20    # Latency to start AWS (sec)
                PanelStat = [0]*PanelNum    # Keeps whether each panel is displayed or not
                TouchedPanelNum = 0 # Keeps the number of panel touched and turned off


                StartRecording()  # Start camera capture / TTL signal output
                StartLickRecording()  # Start an entry of lick log
                LightCycleControlOff()  # Deactivate automatic Light/Dark cycle illumination
                RoofLightOff()  # Turn off the lights on roof (Digital output Ch13)
                InfraredLightOn()   # Turn on the infrared LED illumination (Digital output Ch12)
                if WaterCueType == 'Normal':
                    DigitalOutOn(10)    # Turn on cue LED connected to Ch10
                if WaterCueType == 'Blink':
                    DigitalOutBlinkOn(10)   # Start blinking of cue LED connected to Ch10
                ServoPosInside(3)   # Change the angle of water arm servo connected to Ch3 to inside position
                CreateNormalPanel_All()  #


                Writer_TouchEventTxt = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.txt", 'w')  # Initialize the text exporter for a result file
                Writer_TouchEventTxt.write('TrialNum\tResult\t\t\tyyyy/mm/dd\th:m\ts\n')  # Write item name on the result file
                Writer_TouchEventCsv = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.csv", 'w')
                print("Task #" + str(GetTaskID()) + " is started at " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))  # Enter the start time in the console window of Pycharm

                Timer_Start(5)  # Start a timer #5 to measure the duration of the task
                Phase2 = 2  # Start task from the reward phase
                Phase2_Init = 1 # Flag indicating that initialization of Phase2 has done

            if Phase2 == 0:   # Initiation of new trial
                TaskDur = Timer_GetSec(5)
                print(PanelNum)
                for i in range(PanelNum):
                    ShowPanel(i)
                    PanelStat[i] = 1
                TouchedPanelNum = 0
                Phase2 = 1

            if Phase2 == 1:   # Panel choice
                TouchedPanelID = DetectRoiNosepoke()  # Checks which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID != -1 and TouchedPanelID != 19:  # If any panel is touched
                    TrialNum += 1
                    if PanelStat[TouchedPanelID] == 1:    # If the mouse touched displayed panel
                        PanelStat[TouchedPanelID] = 0
                        HidePanel(TouchedPanelID)
                        TouchedPanelNum += 1
                        if TouchedPanelNum == PanelNum:
                            ServoPosInside(3)    # Move the water nozzle into inside position
                            if WaterCueType == 'Normal':
                                DigitalOutOn(10)  # Turn on cue LED connected to Ch10
                            if WaterCueType == 'Blink':
                                DigitalOutBlinkOn(10)  # Start blinking of cue LED connected to Ch10
                            NowDrinking = 0
                            CorrectNum += 1     # Increase the number of correct response
                            Phase2 = 2  # Start reward phase
                        if Phase2 == 1:
                            Writer_TouchEventTxt.write(str(TrialNum) + '\tPanelTouch\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                            Writer_TouchEventCsv.write(str(TrialNum) + ',1,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                        if Phase2 == 2:
                            Writer_TouchEventTxt.write(str(TrialNum) + '\tPanelTouch(Rewarded)\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                            Writer_TouchEventCsv.write(str(TrialNum) + ',2,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file

                    mOngoingResultVar.set('CorrectNum: ' + str(CorrectNum) + '  IncorrectNum: ' + str(IncorrectNum) + '  TrialNum: ' + str(TrialNum))

                if Timer_GetSec(5) >= TimeLimit * 60:   # If time limit of the task comes
                    TaskDur = Timer_GetSec(5)
                    print("Time limit elapsed")
                    Timer_End(5)    # Stop the timer
                    Phase2 = 5

            if Phase2 == 2:  # Reward phase
                if DetectRoiNosepoke() == 19 and NowDrinking == 0:    # If the mouse initiates nose poking
                    NowDrinking = 1
                    Timer_Start(0)  # Start lick timer
                if NowDrinking == 1:    # If the nose poke has begun
                    if Timer_GetSec(0) >= LickDur:   # If the nosepoke duration exceeds the lick duration
                        Timer_End(0) # End timer for measuring lick duration
                        ServoPosMiddle(3)   # Move water nozzle back to the middle position
                        DigitalOutOff(10)   # Turn off the cue LED
                        NowDrinking = 0
                        Phase2 = 4  # Go to After trial phase

            if Phase2 == 4:  # After trial phase
                if CorrectNum < MaxCorrectNum:  # If the touch number doesn't exceed the maximum number
                    Phase2 = 0
                if CorrectNum >= MaxCorrectNum:  # If the touch number exceeds the maximum number
                    TaskDur = Timer_GetSec(5)  # Keep the task time
                    Phase2 = 5

            if Phase2 == 5:
                ServoPosOutside(5)  # Pull the indicated lever back
                ServoPosOutside(6)
                if CorrectNum < MaxCorrectNum and AwsOn == 'ON':  # If mouse didn't achieved the max correct response
                    Timer_Start(0)
                    Phase2 = 6
                if CorrectNum == MaxCorrectNum or AwsOn == 'OFF':  # If mouse achieved the max correct response
                    Phase2 = -1

            if Phase2 == 6:  # Wait until complemental water supply is started
                if Timer_GetSec(0) >= AWS_Latency:  # If it past indicated latency to start complemental water supply
                    Timer_End(0)
                    ArbitaryWaterSupplyDur = (MaxCorrectNum - CorrectNum) * LickDur * 1000  # Calculate the duration of complemental water supply
                    if WaterCueType == 'Normal':
                        StartArbitaryWaterSupply(3, 10, 0, ArbitaryWaterSupplyDur)  # Start complemental water supply
                    if WaterCueType == 'Blink':
                        StartArbitaryWaterSupply(3, 10, 1, ArbitaryWaterSupplyDur)
                    print("Arbitrary water supply start")
                    Phase2 = 7  # Start AWS

            if Phase2 == 7: # Keep checking until complemental water supply is finished
                if GetArbitaryWaterSupplyStat() == 1:  # If the complemental water supply is finished
                    Phase2 = -1

            if Phase2 == -1 or GetEndTaskNowButtonStat() == 1:  # If the flag is set to finish the task
                LightCycleControlOn()   # Activate automatic light/dark cycle
                for i in range(PanelNum):
                    HidePanel(i)
                ServoPosMiddle(3)   # Moze servo nozzle into middle position
                InfraredLightOff()  # Turn off the infrared LED
                if GetRecordingStat() == 1: # If camera is capturing
                    SetEndRecordingTimer(60)    # Onset a timer to finish video recording after 60 frames (correspond about 2sec) from now

                # Add summary of results into the result file
                Writer_TouchEventTxt.write('CorrectNum:' + str(CorrectNum) + '%\n')
                Writer_TouchEventTxt.write('SessionStartTime: ' + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()) + "\n")
                Writer_TouchEventTxt.write('SessionEndTime: ' + str(TimeNow.month) + '/' + str(TimeNow.day) + ' ' + str(TimeNow.hour) + ':' + str(TimeNow.minute) + ':' + str(TimeNow.second + (TimeNow.microsecond // 1000) / 1000) + "\n")
                Writer_TouchEventTxt.write('TaskDuration(sec): ' + str(TaskDur) + "\n")
                # Add experimental conditions into the result file
                Writer_TouchEventTxt.write('MaxCorrectNum: '+str(MaxCorrectNum)+"\n")
                Writer_TouchEventTxt.write('TimeLimit: ' + str(TimeLimit) + "\n")
                Writer_TouchEventTxt.write('LickDur: ' + str(LickDur)+"\n")
                Writer_TouchEventTxt.write('NextTask: ' + str(NextTask) + "\n")
                Writer_TouchEventTxt.write('NextTaskTh: ' + str(NextTaskTh) + "\n")
                Writer_TouchEventTxt.write('WaterCueType: ' + WaterCueType + "\n")
                Writer_TouchEventTxt.write('AwsOn: ' + AwsOn + "\n")
                Writer_TouchEventTxt.write('RecordFPS: ' + str(GetRecordFps()) + "\n")  # Recorded frame number per second
                Writer_TouchEventTxt.write(GetRoiSensitivity() + "\n")  # Settings of each ROI
                Writer_TouchEventTxt.write(GetServoAngle() + "\n")  # Set angles of each servo

                Writer_TouchEventTxt.close()    # Close the text exporter for the result file
                Writer_TouchEventCsv.close()
                EndLickRecording()  # End lick log recording

                SendMail(DeviceNameVar.get()+' finished task '+str(GetTaskID())+'. TrialNum:'+str(TrialNum)+' Correct:'+str(CorrectNum)+' Incorrect:'+str(IncorrectNum)+' Rate:'+str(CorrectRate)+'% Dur:'+str(round(Timer_GetSec(5) / 60,1))+' min','The task is finished.') # Send a email (correct number and task duration are added to email title)

                if IsHousingAnalysis == 1 and Phase2 == -1:  # If it is housing analysis
                    if CorrectNum >= NextTaskTh:  # If the score exceed the criteria to switch to the next task
                        SwitchTask(NextTask)  # Onset the task switching trigger
                        print("Task was switched to task#" + str(NextTask) + "  " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

                if IsHousingAnalysis == 0:
                    RoofLightOn()

                Phase = 1  # Go back to the task-waiting phase
                Phase2 = 0
                Phase2_Init = 0

            SetDispVariable(0, 'Phase2', str(Phase2))  # Display "Phase2" value on the bottom of main window
    return

def Task5():   # Spatial discrimination task
    global Phase
    Phase0_Init=0
    Phase1_Init=0
    Phase2_Init=0
    while EndFlag==0:
        OperantHouseUpdate()
        if GetBackButtonStat()==1:    # If "Back" button is clicked
            break   # Back to the task select phase
        if Phase == 0:  # Parameter inputs
            if Phase0_Init == 0:
                # Make GUI for the setting of the parameters for this task
                RemoveMainRightWidget() # Remove task buttons
                PutStartBackButton()    # Put start/back buttons

                #mSpace = ttk.Label(MainWindowRightFrame, text=' ').grid(row=0, column=1)  # Used just as spacer
                ColumnWidth = 14

                mMaxCorrectNum = ttk.Label(MainWindowRightFrame, text='MaxCorrectNum', width=ColumnWidth).grid(row=0, column=2, sticky=W)    # Put label
                MaxCorrectNumVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iMaxCorrectNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxCorrectNumVar, width=ColumnWidth).grid(row=1, column=2)  # Place entry field

                mMaxTrialNum = ttk.Label(MainWindowRightFrame, text='MaxTrialNum', width=ColumnWidth).grid(row=0, column=3, sticky=W)
                MaxTrialNumVar = IntVar(MainWindowRoot)
                iMaxTrialNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxTrialNumVar, width=ColumnWidth).grid(row=1, column=3)

                mTimeLimit = ttk.Label(MainWindowRightFrame, text='TimeLimit(min)', width=ColumnWidth).grid(row=0, column=4, sticky=W)
                TimeLimitVar = DoubleVar(MainWindowRoot)
                iTimeLimit = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitVar, width=ColumnWidth).grid(row=1, column=4)

                mPunishDur = ttk.Label(MainWindowRightFrame, text='PunishDur(s)', width=ColumnWidth).grid(row=0, column=5, sticky=W)
                PunishDurVar = DoubleVar(MainWindowRoot)
                iPunishDur = ttk.Entry(MainWindowRightFrame, textvariable=PunishDurVar, width=ColumnWidth).grid(row=1, column=5)

                mIti = ttk.Label(MainWindowRightFrame, text='ITI(s)', width=ColumnWidth).grid(row=0, column=6, sticky=W)
                ItiVar = DoubleVar(MainWindowRoot)
                iIti = ttk.Entry(MainWindowRightFrame, textvariable=ItiVar, width=ColumnWidth).grid(row=1, column=6)

                mLickDur = ttk.Label(MainWindowRightFrame, text='LickDur(s)', width=ColumnWidth).grid(row=0, column=7, sticky=W)
                LickDurVar = DoubleVar(MainWindowRoot)
                iLickDur = ttk.Entry(MainWindowRightFrame, textvariable=LickDurVar, width=ColumnWidth).grid(row=1, column=7)

                mNextTaskTh = ttk.Label(MainWindowRightFrame, text='NextTaskTh(Correct%)', width=ColumnWidth).grid(row=2, column=2, sticky=W)
                NextTaskThVar = DoubleVar(MainWindowRoot)
                iNextTaskTh = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskThVar, width=ColumnWidth).grid(row=3, column=2)

                mNextTask = ttk.Label(MainWindowRightFrame, text='NextTask#', width=ColumnWidth).grid(row=2, column=3, sticky=W)
                NextTaskVar = IntVar(MainWindowRoot)
                iNextTask = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskVar, width=ColumnWidth).grid(row=3, column=3)

                mCorrectPos = ttk.Label(MainWindowRightFrame, text='CorrectPos', width=ColumnWidth).grid(row=2, column=4, sticky=W)    # Put label
                CorrectPosVar = StringVar(MainWindowRightFrame)  # Declare variable receiving value from the entry field
                tCorrectPos = OptionMenu(MainWindowRightFrame, CorrectPosVar, "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20").grid(row=3, column=4) # Place drop-down list

                mPanelType = ttk.Label(MainWindowRightFrame, text='PanelType', width=ColumnWidth).grid(row=2, column=5, sticky=W)
                PanelTypeVar = StringVar(MainWindowRightFrame)
                tPanelType = OptionMenu(MainWindowRightFrame, PanelTypeVar, "Normal", "Blink", "Textured").grid(row=3, column=5)

                mWaterCueType = ttk.Label(MainWindowRightFrame, text='WaterCueType', width=ColumnWidth).grid(row=2, column=6, sticky=W)
                WaterCueTypeVar = StringVar(MainWindowRightFrame)
                tWaterCueType = OptionMenu(MainWindowRightFrame, WaterCueTypeVar, "Normal", "Blink").grid(row=3, column=6)

                mLitPattern = ttk.Label(MainWindowRightFrame, text='LitPattern', width=ColumnWidth).grid(row=2, column=7, sticky=W)
                LitPatternVar = StringVar(MainWindowRightFrame)
                tLitPattern = OptionMenu(MainWindowRightFrame, LitPatternVar, "Random", "All").grid(row=3, column=7)

                mPunishWithLight = ttk.Label(MainWindowRightFrame, text='PunishLight', width=ColumnWidth).grid(row=2, column=8, sticky=W)
                PunishWithLightVar = StringVar(MainWindowRightFrame)
                tPunishWithLight = OptionMenu(MainWindowRightFrame, PunishWithLightVar, "ON", "OFF").grid(row=3, column=8)

                mAwsOn = ttk.Label(MainWindowRightFrame, text='AWS', width=ColumnWidth).grid(row=4, column=2, sticky=W)
                AwsOnVar = StringVar(MainWindowRightFrame)
                tAwsOn = OptionMenu(MainWindowRightFrame, AwsOnVar, "ON", "OFF").grid(row=5, column=2)

                Str = "ParametersForTask" + str(GetTaskID())
                if os.path.exists(Str + '/MaxCorrectNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxCorrectNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxCorrectNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxCorrectNumVar.set(80)  # Default value

                if os.path.exists(Str + '/MaxTrialNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxTrialNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxTrialNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxTrialNumVar.set(110)  # Default value

                if os.path.exists(Str + '/TimeLimit.dat') == True:  # If save file exists
                    with open(Str + '/TimeLimit.dat', 'rb') as PickleInst[GetTaskID()]:
                        TimeLimitVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    TimeLimitVar.set(360)  # Default value

                if os.path.exists(Str + '/PunishDur.dat') == True:  # If save file exists
                    with open(Str + '/PunishDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishDurVar.set(15)  # Default value

                if os.path.exists(Str + '/Iti.dat') == True:  # If save file exists
                    with open(Str + '/Iti.dat', 'rb') as PickleInst[GetTaskID()]:
                        ItiVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    ItiVar.set(1)  # Default value
                if os.path.exists(Str + '/LickDur.dat') == True:  # If save file exists
                    with open(Str + '/LickDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        LickDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    LickDurVar.set(2)  # Default value

                if os.path.exists(Str + '/NextTaskTh.dat') == True:  # If save file exists
                    with open(Str + '/NextTaskTh.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskThVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskThVar.set(80)  # Default value
                if os.path.exists(Str + '/NextTask.dat') == True:  # If save file exists
                    with open(Str + '/NextTask.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskVar.set(5)  # Default value

                if os.path.exists(Str + '/CorrectPos.dat') == True:  # If save file exists
                    with open(Str + '/CorrectPos.dat', 'rb') as PickleInst[GetTaskID()]:
                        CorrectPosVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    CorrectPosVar.set(0)  # Default value

                if os.path.exists(Str + '/PanelType.dat') == True:  # If save file exists
                    with open(Str + '/PanelType.dat', 'rb') as PickleInst[GetTaskID()]:
                        PanelTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PanelTypeVar.set('Normal')  # Default value

                if os.path.exists(Str + '/WaterCueType.dat') == True:  # If save file exists
                    with open(Str + '/WaterCueType.dat', 'rb') as PickleInst[GetTaskID()]:
                        WaterCueTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    WaterCueTypeVar.set('Blink')  # Default value

                if os.path.exists(Str + '/LitPattern.dat') == True:  # If save file exists
                    with open(Str + '/LitPattern.dat', 'rb') as PickleInst[GetTaskID()]:
                        LitPatternVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    LitPatternVar.set('All')  # Default value
                if os.path.exists(Str + '/PunishWithLight.dat') == True:  # If save file exists
                    with open(Str + '/PunishWithLight.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishWithLightVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishWithLightVar.set('ON')  # Default value
                if os.path.exists(Str + '/AwsOn.dat') == True:  # If save file exists
                    with open(Str + '/AwsOn.dat', 'rb') as PickleInst[GetTaskID()]:
                        AwsOnVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    AwsOnVar.set('ON')  # Default value

                RemoveAllRoiGui()
                for i in range(GetCurrentPanelNum()):
                    PutRoiGui(i, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)  Set panel ROIs
                PutRoiGui(19, 0, 0, 1)  # Put ROI Window gudget again

                RemoveAllDigitalOutGui()
                PutDigitalOutGui(10)
                PutDigitalOutGui(12)
                PutDigitalOutGui(13)

                RemoveAllServoGui()
                PutServoGui(3)

                Phase0_Init = 1

        if GetSaveTrgStat() == 1:    # If save trigger is on
            # Parameters of each task are saved into different folder
            Str="ParametersForTask"+str(GetTaskID())   # Path to the folder for saving of parameters
            if os.path.exists(Str) == False:    # If folder for saving parameters is not exist
                os.mkdir(Str)   # Make folder for saving
            with open(Str+'/MaxCorrectNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxCorrectNumVar.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/MaxTrialNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxTrialNumVar.get(),PickleInst[GetTaskID()])     # Save
            with open(Str + '/TimeLimit.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TimeLimitVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str+'/PunishDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishDurVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/Iti.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(ItiVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/LickDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(LickDurVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str + '/NextTask.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str+'/NextTaskTh.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskThVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/CorrectPos.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(CorrectPosVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/PanelType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PanelTypeVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/WaterCueType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(WaterCueTypeVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/LitPattern.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(LitPatternVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/PunishWithLight.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishWithLightVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/AwsOn.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(AwsOnVar.get(), PickleInst[GetTaskID()])     # Save

        if Phase == 1:  # Wait for starting of task
            if Phase1_Init == 0:
                PutPreTaskButton()
                mStatusVar = StringVar(MainWindowRoot)
                mStatus = ttk.Label(MainWindowRightFrame, textvariable=mStatusVar)
                mStatus.place(x=10, y=0)
                mOngoingResultVar = StringVar(MainWindowRoot)
                Phase1_Init = 1
            mStatusVar.set('Spatial discrimination task (' + str(GetTaskID()) + ')    Waiting...')
            if IsStartTime() == 1:
                StartNow()
        if Phase == 2:  # During task
            if Phase2_Init == 0: # Initialization of the task
                PutEndTaskNowButton()

                mStatusVar.set('Spatial discrimination task (' + str(GetTaskID()) + ')    Start time ' + str(TaskStartedMonth) + '/' + str(TaskStartedDay) + ' ' + str(TaskStartedHour) + ':' + str(TaskStartedMinute) + '    Running')
                mOngoingResult = ttk.Label(MainWindowRightFrame, textvariable=mOngoingResultVar)
                mOngoingResult.place(x=10, y=18)

                # Convert StringVars of parameters into integer or normal string to use in the following
                MaxCorrectNum=int(MaxCorrectNumVar.get())
                MaxTrialNum = int(MaxTrialNumVar.get())
                TimeLimit = float(TimeLimitVar.get())
                PunishDur = float(PunishDurVar.get())
                Iti = float(ItiVar.get())
                LickDur = float(LickDurVar.get())
                NextTask = int(NextTaskVar.get())
                NextTaskTh = float(NextTaskThVar.get())
                CorrectPos = int(CorrectPosVar.get())
                PanelType = PanelTypeVar.get()
                WaterCueType =WaterCueTypeVar.get()
                LitPattern = LitPatternVar.get()
                PunishWithLight = PunishWithLightVar.get()
                AwsOn = AwsOnVar.get()

                StartLickRecording()
                RoofLightOff()
                InfraredLightOn()
                if WaterCueType == 'Normal':
                    DigitalOutOn(10)
                if WaterCueType == 'Blink':
                    DigitalOutBlinkOn(10)
                ServoPosInside(3)
                if PanelType=='Normal':
                    CreateNormalPanel_All()
                if PanelType=='Blink':
                    CreateBlinkPanel_All()
                if PanelType=='Textured':
                    CreateTexturedPanel_All(0)

                # Declar local variables for this task
                TotalTouchNum = 0
                CorrectNum = 0
                IncorrectNum = 0
                CorrectRate = 0
                TaskDur = 0

                LightCycleControlOff()
                DoneCorrectResponse = 1
                NowDrinking = 0
                AWS_Latency=20
                StartRecording()    # Start camera capturing and sending of TTL

                TrialNum=0

                Timer_Start(5)  # Task time limit timer start
                Phase2 = 2
                Phase2_Init = 1

                Writer_TouchEventTxt = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.txt",'w')  # Initialize the text exporter
                Writer_TouchEventCsv = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.csv",'w')  # Initialize the text exporter
                Writer_TouchEventTxt.write('TrialNum\tResult\t\t\tyyyy/mm/dd\th:m\ts\n')  # Write item name
                print("Task #" + str(GetTaskID()) + " is started at " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(
                    GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

            if Phase2 == 0:   # Initiation of new trial
                TaskDur = Timer_GetSec(5)
                DoneCorrectResponse=0
                TrialNum += 1
                if LitPattern=='All':
                    ShowAllPanel()
                if LitPattern=='Random':
                    Rnd = random.random()*GetCurrentPanelNum()
                    ShowPanel(int(Rnd))

                Timer_Start(0)  # Start the latency timer
                Phase2 += 1
            if Phase2 == 1:   # Panel presentation
                TouchedPanelID = DetectRoiNosepoke() # Examine which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID != -1 and TouchedPanelID != 19:
                    if TouchedPanelID == CorrectPos: # If mouse touchs correct panel
                        DoneCorrectResponse = 1
                        ServoPosInside(3)  # Move water nozzle to the inside position
                        NowDrinking = 0
                        CorrectNum += 1  # Increase the number of correct respon
                        TotalTouchNum+=1
                        mOngoingResultVar.set('CorrectNum:'+str(CorrectNum)+'  IncorrectNum:'+str(IncorrectNum)+'  TotalNum:'+str(TotalTouchNum)+'  Correct:'+str(round(CorrectNum*100.0/TotalTouchNum, 2))+'%')
                        Writer_TouchEventTxt.write(str(TrialNum) + '\tPanelTouched(Correct)\t' +str(TouchedPanelID)+'\t'+ str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',1,' +str(TouchedPanelID)+','+ str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the csv file
                        HideAllPanel()
                        Timer_End(0)
                        if WaterCueType == 'Normal':
                            DigitalOutOn(10)
                        if WaterCueType == 'Blink':
                            DigitalOutBlinkOn(10)
                        Phase2 = 2  # Start reward phase
                    if TouchedPanelID != CorrectPos: # If mouse touchs wrong panel
                        ServoPosOutside(3)
                        if PunishWithLight == 'ON':
                            RoofLightOn()  # Turn on roof light
                        IncorrectNum += 1
                        TotalTouchNum += 1
                        mOngoingResultVar.set('CorrectNum:' + str(CorrectNum) + '  IncorrectNum:' + str(IncorrectNum) + '  TotalNum:' + str(TotalTouchNum) + '  Correct(%):' + str(round(CorrectNum * 100.0 / TotalTouchNum, 2)))
                        Writer_TouchEventTxt.write(str(TrialNum) + '\tPanelTouched(Wrong)\t' +str(TouchedPanelID)+'\t'+ str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',0,' +str(TouchedPanelID)+','+ str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the csv file
                        HideAllPanel()
                        Timer_End(0)  # End timer1
                        Timer_Start(0)  # Start punish timer
                        Phase2 = 5  # Start punishment phase
                        DigitalOutOn(10)    #TTL onset

                if Timer_GetSec(5) >= TimeLimit * 60:   # If time limit is exceeded
                    TaskDur = Timer_GetSec(5)
                    Timer_End(5)
                    Phase2 = 6
            if Phase2 == 2:  # Reward phase
                if DetectRoiNosepoke() == 19 and NowDrinking == 0:    # If the mouse initiates nose poke
                    NowDrinking = 1
                    Timer_Start(0)  # Start lick timer
                if NowDrinking == 1:
                    if DoneCorrectResponse == 1 and Timer_GetSec(0) >= LickDur:   # If lick time exceed the designated time
                        Timer_End(0) # End lick timer
                        ServoPosMiddle(3)    # Move water nozzle to the intermediate position
                        DigitalOutOff(10)
                        NowDrinking = 0
                        Timer_Start(0)  # Start ITI timer
                        Phase2 = 3

            if Phase2 == 3:   # ITI
                if Timer_GetSec(0) >= Iti:  # If ITI is passed
                    Timer_End(0)
                    Phase2 = 0  # Go to the next trial
                if CorrectNum >= MaxCorrectNum or TotalTouchNum >= MaxTrialNum: # If mouse achieved criteria of finishing the task
                    Timer_End(5)
                    ServoPosMiddle(3)
                    DigitalOutOff(10)
                    Timer_Start(0)  # Timer for interval between task and arbitary water supply is started
                    Phase2 = 6  # Go to the AWS
            if Phase2 == 5:   # Punishment phase
                if Timer_GetSec(0) >= PunishDur:    # If punishment time is passed
                    RoofLightOff()
                    ServoPosMiddle(3)    # Move water nozzle to the intermediate position
                    Timer_End(0)  # End punishment timer1
                    Timer_Start(0)  # Start ITI timer
                    Phase2 = 3
                    DigitalOutOff(10)      #TTL offset
            if Phase2==6:
                HideAllPanel()
                if CorrectNum < MaxCorrectNum and AwsOn=='ON':  # If mouse didn't achieved the max correct response
                    Timer_Start(0)
                    Phase2 = 7
                if CorrectNum == MaxCorrectNum or AwsOn=='OFF':  # If mouse achieved the max correct response
                    Phase2 = -1
            if Phase2==7:   # Wait until arbitary water suuply is started
                if Timer_GetSec(0) >= 20:   # If the interval is past 60
                    Timer_End(0)
                    ArbitaryWaterSupplyDur=(MaxCorrectNum - CorrectNum) * LickDur * 1000    # Caliculate duration of complement water supply
                    if WaterCueType == 'Normal':
                        StartArbitaryWaterSupply(3,10,0,ArbitaryWaterSupplyDur) # Start complement water supply
                    if WaterCueType == 'Blink':
                        StartArbitaryWaterSupply(3,10,1,ArbitaryWaterSupplyDur) # Start complement water supply
                    print("AWSstart")
                    Phase2=8
            if Phase2==8:
                if GetArbitaryWaterSupplyStat()==1: # If complement water supply is finished
                    Phase2 = -1

            if Phase2 == -1 or GetEndTaskNowButtonStat() == 1:  # Task finish phase
                LightCycleControlOn()
                ServoPosMiddle(3)
                DeleteAllPanel()
                InfraredLightOff()
                if GetRecordingStat() == 1:
                    SetEndRecordingTimer(60)
                if CorrectNum > 0 or IncorrectNum > 0:
                    CorrectRate = int(CorrectNum * 100.0 / TotalTouchNum)
                    Writer_TouchEventTxt.write('TotalNum:'+str(TotalTouchNum)+'  Correct num:'+str(CorrectNum)+'  Incorrect num:'+str(IncorrectNum)+'  Correct rate'+str(CorrectRate)+'%'+"\n") #結果テキストの一番最後に成績のまとめを記入
                Writer_TouchEventTxt.write('SessionStartTime: ' + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()) + "\n")
                Writer_TouchEventTxt.write('SessionEndTime: ' + str(TimeNow.month) + '/' + str(TimeNow.day) + ' ' + str(TimeNow.hour) + ':' + str(TimeNow.minute) + ':' + str(TimeNow.second + (TimeNow.microsecond // 1000) / 1000) + "\n")
                Writer_TouchEventTxt.write('TaskDuration(sec): ' + str(TaskDur) + "\n")
                Writer_TouchEventTxt.write('MaxCorrectNum: '+str(MaxCorrectNum)+"\n")
                Writer_TouchEventTxt.write('MaxTrialNum: ' + str(MaxTrialNum) + "\n")
                Writer_TouchEventTxt.write('TimeLimit: ' + str(TimeLimit) + "\n")
                Writer_TouchEventTxt.write('PunishDur: ' + str(PunishDur) + "\n")
                Writer_TouchEventTxt.write('Iti: ' + str(Iti) + "\n")
                Writer_TouchEventTxt.write('LickDur: ' + str(LickDur) + "\n")
                Writer_TouchEventTxt.write('NextTask: ' + str(NextTask) + "\n")
                Writer_TouchEventTxt.write('NextTaskTh: ' + str(NextTaskTh)+"\n")
                Writer_TouchEventTxt.write('CorrectPos: ' + str(CorrectPos) + "\n")
                Writer_TouchEventTxt.write('PanelType: ' + str(PanelType) + "\n")
                Writer_TouchEventTxt.write('WaterCueType: ' + str(WaterCueType) + "\n")
                Writer_TouchEventTxt.write('LitPattern: ' + str(LitPattern) + "\n")
                Writer_TouchEventTxt.write('PunishLight: ' + str(PunishWithLight)+"\n")
                Writer_TouchEventTxt.write('RecordFPS: ' + str(GetRecordFps()) + "\n")
                Writer_TouchEventTxt.write('AWS: ' + AwsOn + "\n")
                Writer_TouchEventTxt.write('AWS_Latency: ' + str(AWS_Latency) + "\n")
                Writer_TouchEventTxt.write(GetRoiSensitivity() + "\n")
                Writer_TouchEventTxt.write(GetServoAngle() + "\n")

                Writer_TouchEventTxt.close()
                Writer_TouchEventCsv.close()
                EndLickRecording()
                SendMail(DeviceNameVar.get() + ' finished task '+str(GetTaskID())+'. Correct:' + str(CorrectNum) + ' Incorrect:' + str(IncorrectNum) + ' Correct:'+str(CorrectRate)+'% Dur:' + str(round(Timer_GetSec(5) / 60,1)) + ' min', 'The task is finished.')

                if IsHousingAnalysis == 1 and Phase2 == -1:  # If it is housing analysis
                    if CorrectRate >= NextTaskTh:  # If the score exceed the criteria to switch the next task
                        SwitchTask(NextTask)  # Onset task switch trigger
                        print("Task is switched to task#" + str(NextTask) + "  " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

                if IsHousingAnalysis == 0:
                    RoofLightOn()
                Phase = 1  # Go back to the task-waiting phase
                Phase2 = 0
                Phase2_Init = 0
            SetDispVariable(0, 'Phase2', str(Phase2))  # Display "Phase2" value on the main window
    return

def Task6():    #DNMTP
    global Phase
    Phase0_Init = 0
    Phase1_Init = 0
    Phase2_Init = 0
    while EndFlag == 0:
        OperantHouseUpdate()
        if GetBackButtonStat()==1:    # If "Back" button is clicked
            break   # Back to the task select phase
        if Phase == 0:  # Parameter inputs
            if Phase0_Init == 0:
                # Make GUI for the setting of the parameters for this task
                RemoveMainRightWidget()  # Remove task buttons
                PutStartBackButton()  # Put start/back buttons

                ColumnWidth = 10
                Row = 0  # Begin a new line
                Column = 0
                XShift = 0
                XShiftLength = 80
                YShift = 0

                mMaxCorrectNum = ttk.Label(MainWindowRightFrame, text='MaxCorrect', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                MaxCorrectNumVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iMaxCorrectNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxCorrectNumVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mMaxTrialNum = ttk.Label(MainWindowRightFrame, text='MaxTrial', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                MaxTrialNumVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iMaxTrialNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxTrialNumVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mTimeLimit = ttk.Label(MainWindowRightFrame, text='Limit(min)', width=11).grid(row=Row, column=Column, sticky=W)  # Put label
                TimeLimitVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iTimeLimit = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitVar, width=11).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mPunishDur = ttk.Label(MainWindowRightFrame, text='PunishDur(s)', width=12).grid(row=Row, column=Column, sticky=W)  # Put label
                PunishDurVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iPunishDur = ttk.Entry(MainWindowRightFrame, textvariable=PunishDurVar, width=12).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mLickDur = ttk.Label(MainWindowRightFrame, text='LickDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                LickDurVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iLickDur = ttk.Entry(MainWindowRightFrame, textvariable=LickDurVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mIti = ttk.Label(MainWindowRightFrame, text='ITI(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                ItiVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iIti = ttk.Entry(MainWindowRightFrame, textvariable=ItiVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mDelayAllowFactor = ttk.Label(MainWindowRightFrame, text='ValidDelay(%)', width=12).grid(row=Row, column=Column, sticky=W)  # Put label
                DelayAllowFactorVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelayAllowFactor = ttk.Entry(MainWindowRightFrame, textvariable=DelayAllowFactorVar, width=12).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mRateTh = ttk.Label(MainWindowRightFrame, text='RateTh(%)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                RateThVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iRateTh = ttk.Entry(MainWindowRightFrame, textvariable=RateThVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mDayTh = ttk.Label(MainWindowRightFrame, text='DayTh(d)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                DayThVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDayTh = ttk.Entry(MainWindowRightFrame, textvariable=DayThVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mStartSession = ttk.Label(MainWindowRightFrame, text='StartSession', width=12).grid(row=Row, column=Column, sticky=W)  # Put label
                StartSessionVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iStartSession = ttk.Entry(MainWindowRightFrame, textvariable=StartSessionVar, width=12).grid(row=Row + 1, column=Column)  # Place entry field

                Row += 2  # Begin a new line
                Column = 0

                mSeed = ttk.Label(MainWindowRightFrame, text='Seed', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                SeedVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iSeed = ttk.Entry(MainWindowRightFrame, textvariable=SeedVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mNextTask = ttk.Label(MainWindowRightFrame, text='NextTask', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                NextTaskVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iNextTask = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mTaskType = ttk.Label(MainWindowRightFrame, text='TaskType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                TaskTypeVar = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                tTaskType = OptionMenu(MainWindowRightFrame, TaskTypeVar, "DNMTP1", "DNMTP2", "DMTP1", "DMTP2").grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mWaterCueType = ttk.Label(MainWindowRightFrame, text='WaterCue', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                WaterCueTypeVar = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                tWaterCueType = OptionMenu(MainWindowRightFrame, WaterCueTypeVar, "Normal", "Blink").grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mPunishWithLight = ttk.Label(MainWindowRightFrame, text='PunishLight', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                PunishWithLightVar = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                tPunishWithLight = OptionMenu(MainWindowRightFrame, PunishWithLightVar, "ON", "OFF").grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mAwsOn = ttk.Label(MainWindowRightFrame, text='AWS', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                AwsOnVar = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                tAwsOn = OptionMenu(MainWindowRightFrame, AwsOnVar, "ON", "OFF").grid(row=Row + 1, column=Column)  # Place entry field

                Row += 2  # Begin a new line
                Column = 0

                ColumnWidth = 10
                YShift=94
                # mDelay0 = ttk.Label(MainWindowRightFrame, text='Delay0(sec)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                mDelay0 = ttk.Label(MainWindowRightFrame, text='Delay0(sec)', width=ColumnWidth).place(x=XShift, y=YShift)
                Delay0Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                # iDelay0 = ttk.Entry(MainWindowRightFrame, textvariable=Delay0Var, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
                iDelay0 = ttk.Entry(MainWindowRightFrame, textvariable=Delay0Var, width=ColumnWidth).place(x=XShift, y=YShift+20)  # Place entry field
                XShift += XShiftLength
                mDelay1 = ttk.Label(MainWindowRightFrame, text='Delay1', width=ColumnWidth).place(x=XShift, y=YShift)  # Put label
                Delay1Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay1 = ttk.Entry(MainWindowRightFrame, textvariable=Delay1Var, width=ColumnWidth).place(x=XShift, y=YShift+20)  # Place entry field
                XShift += XShiftLength
                mDelay2 = ttk.Label(MainWindowRightFrame, text='Delay2', width=ColumnWidth).place(x=XShift, y=YShift)  # Put label
                Delay2Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay2 = ttk.Entry(MainWindowRightFrame, textvariable=Delay2Var, width=ColumnWidth).place(x=XShift, y=YShift+20)  # Place entry field
                XShift += XShiftLength
                mDelay3 = ttk.Label(MainWindowRightFrame, text='Delay3', width=ColumnWidth).place(x=XShift, y=YShift)  # Put label
                Delay3Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay3 = ttk.Entry(MainWindowRightFrame, textvariable=Delay3Var, width=ColumnWidth).place(x=XShift, y=YShift+20)  # Place entry field
                XShift += XShiftLength
                mDelay4 = ttk.Label(MainWindowRightFrame, text='Delay4', width=ColumnWidth).place(x=XShift, y=YShift)  # Put label
                Delay4Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay4 = ttk.Entry(MainWindowRightFrame, textvariable=Delay4Var, width=ColumnWidth).place(x=XShift, y=YShift+20)  # Place entry field
                XShift += XShiftLength
                mDelay5 = ttk.Label(MainWindowRightFrame, text='Delay5', width=ColumnWidth).place(x=XShift, y=YShift)  # Put label
                Delay5Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay5 = ttk.Entry(MainWindowRightFrame, textvariable=Delay5Var, width=ColumnWidth).place(x=XShift, y=YShift+20)  # Place entry field
                XShift += XShiftLength
                mDelay6 = ttk.Label(MainWindowRightFrame, text='Delay6', width=ColumnWidth).place(x=XShift, y=YShift)  # Put label
                Delay6Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay6 = ttk.Entry(MainWindowRightFrame, textvariable=Delay6Var, width=ColumnWidth).place(x=XShift, y=YShift+20)  # Place entry field
                XShift += XShiftLength
                mDelay7 = ttk.Label(MainWindowRightFrame, text='Delay7', width=ColumnWidth).place(x=XShift, y=YShift)  # Put label
                Delay7Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay7 = ttk.Entry(MainWindowRightFrame, textvariable=Delay7Var, width=ColumnWidth).place(x=XShift, y=YShift+20)  # Place entry field
                XShift += XShiftLength
                mDelay8 = ttk.Label(MainWindowRightFrame, text='Delay8', width=ColumnWidth).place(x=XShift, y=YShift)  # Put label
                Delay8Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay8 = ttk.Entry(MainWindowRightFrame, textvariable=Delay8Var, width=ColumnWidth).place(x=XShift, y=YShift+20)  # Place entry field
                XShift += XShiftLength
                mDelay9 = ttk.Label(MainWindowRightFrame, text='Delay9', width=ColumnWidth).place(x=XShift, y=YShift)  # Put label
                Delay9Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay9 = ttk.Entry(MainWindowRightFrame, textvariable=Delay9Var, width=ColumnWidth).place(x=XShift, y=YShift+20)  # Place entry field

                Str = "ParametersForTask" + str(GetTaskID())
                if os.path.exists(Str + '/MaxCorrectNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxCorrectNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxCorrectNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxCorrectNumVar.set(80)  # Default value

                if os.path.exists(Str + '/MaxTrialNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxTrialNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxTrialNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxTrialNumVar.set(999)  # Default value

                if os.path.exists(Str + '/TimeLimit.dat') == True:  # If save file exists
                    with open(Str + '/TimeLimit.dat', 'rb') as PickleInst[GetTaskID()]:
                        TimeLimitVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    TimeLimitVar.set(600)  # Default value

                if os.path.exists(Str + '/PunishDur.dat') == True:  # If save file exists
                    with open(Str + '/PunishDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishDurVar.set(10)  # Default value

                if os.path.exists(Str + '/LickDur.dat') == True:  # If save file exists
                    with open(Str + '/LickDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        LickDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    LickDurVar.set(2)  # Default value

                if os.path.exists(Str + '/Iti.dat') == True:  # If save file exists
                    with open(Str + '/Iti.dat', 'rb') as PickleInst[GetTaskID()]:
                        ItiVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    ItiVar.set(30)  # Default value

                if os.path.exists(Str + '/DelayAllowFactor.dat') == True:  # If save file exists
                    with open(Str + '/DelayAllowFactor.dat', 'rb') as PickleInst[GetTaskID()]:
                        DelayAllowFactorVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    DelayAllowFactorVar.set(130)  # Default value

                if os.path.exists(Str + '/RateTh.dat') == True:  # If save file exists
                    with open(Str + '/RateTh.dat', 'rb') as PickleInst[GetTaskID()]:
                        RateThVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    RateThVar.set(80)  # Default value

                if os.path.exists(Str + '/DayTh.dat') == True:  # If save file exists
                    with open(Str + '/DayTh.dat', 'rb') as PickleInst[GetTaskID()]:
                        DayThVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    DayThVar.set(2)  # Default value

                if os.path.exists(Str + '/StartSession.dat') == True:  # If save file exists
                    with open(Str + '/StartSession.dat', 'rb') as PickleInst[GetTaskID()]:
                        StartSessionVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    StartSessionVar.set(0)  # Default value

                if os.path.exists(Str + '/Seed.dat') == True:  # If save file exists
                    with open(Str + '/Seed.dat', 'rb') as PickleInst[GetTaskID()]:
                        SeedVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    SeedVar.set(0)  # Default value
                if os.path.exists(Str + '/NextTask.dat') == True:  # If save file exists
                    with open(Str + '/NextTask.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskVar.set(6)  # Default value
                if os.path.exists(Str + '/TaskType.dat') == True:  # If save file exists
                    with open(Str + '/TaskType.dat', 'rb') as PickleInst[GetTaskID()]:
                        TaskTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    TaskTypeVar.set('DNMTP1')  # Default value

                if os.path.exists(Str + '/WaterCueType.dat') == True:  # If save file exists
                    with open(Str + '/WaterCueType.dat', 'rb') as PickleInst[GetTaskID()]:
                        WaterCueTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    WaterCueTypeVar.set('Normal')  # Default value

                if os.path.exists(Str + '/PunishWithLight.dat') == True:  # If save file exists
                    with open(Str + '/PunishWithLight.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishWithLightVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishWithLightVar.set('ON')  # Default value

                if os.path.exists(Str + '/Delay0.dat') == True:  # If save file exists
                    with open(Str + '/Delay0.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay0Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay0Var.set('1')  # Default value
                if os.path.exists(Str + '/AwsOn.dat') == True:  # If save file exists
                    with open(Str + '/AwsOn.dat', 'rb') as PickleInst[GetTaskID()]:
                        AwsOnVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    AwsOnVar.set('OFF')  # Default value
                if os.path.exists(Str + '/Delay1.dat') == True:  # If save file exists
                    with open(Str + '/Delay1.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay1Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay1Var.set('')  # Default value
                if os.path.exists(Str + '/Delay2.dat') == True:  # If save file exists
                    with open(Str + '/Delay2.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay2Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay2Var.set('')  # Default value
                if os.path.exists(Str + '/Delay3.dat') == True:  # If save file exists
                    with open(Str + '/Delay3.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay3Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay3Var.set('')  # Default value
                if os.path.exists(Str + '/Delay4.dat') == True:  # If save file exists
                    with open(Str + '/Delay4.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay4Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay4Var.set('')  # Default value
                if os.path.exists(Str + '/Delay5.dat') == True:  # If save file exists
                    with open(Str + '/Delay5.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay5Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay5Var.set('')  # Default value
                if os.path.exists(Str + '/Delay6.dat') == True:  # If save file exists
                    with open(Str + '/Delay6.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay6Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay6Var.set('')  # Default value
                if os.path.exists(Str + '/Delay7.dat') == True:  # If save file exists
                    with open(Str + '/Delay7.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay7Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay7Var.set('')  # Default value
                if os.path.exists(Str + '/Delay8.dat') == True:  # If save file exists
                    with open(Str + '/Delay8.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay8Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay8Var.set('')  # Default value
                if os.path.exists(Str + '/Delay9.dat') == True:  # If save file exists
                    with open(Str + '/Delay9.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay9Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay9Var.set('')  # Default value

                RemoveAllRoiGui()
                PutRoiGui(0, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(1, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(2, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(19, 0, 0, 1)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)

                RemoveAllDigitalOutGui()
                PutDigitalOutGui(10)
                PutDigitalOutGui(12)
                PutDigitalOutGui(13)

                RemoveAllServoGui()
                PutServoGui(3)
                Phase0_Init = 1

        if GetSaveTrgStat() == 1:  # If save trigger is on
            # Parameters of each task are saved into different folder
            Str = "ParametersForTask" + str(GetTaskID())  # Path to the folder for saving of parameters
            if os.path.exists(Str) == False:  # If folder for saving parameters is not exist
                os.mkdir(Str)  # Make folder for saving
            with open(Str + '/MaxCorrectNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxCorrectNumVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/MaxTrialNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxTrialNumVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/TimeLimit.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TimeLimitVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/PunishDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishDurVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/LickDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(LickDurVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Iti.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(ItiVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/DelayAllowFactor.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(DelayAllowFactorVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/RateTh.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(RateThVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/DayTh.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(DayThVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/StartSession.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(StartSessionVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Seed.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(SeedVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/NextTask.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/TaskType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TaskTypeVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/WaterCueType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(WaterCueTypeVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/PunishWithLight.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishWithLightVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/AwsOn.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(AwsOnVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Delay0.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay0Var.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Delay1.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay1Var.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Delay2.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay2Var.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Delay3.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay3Var.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Delay4.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay4Var.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Delay5.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay5Var.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Delay6.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay6Var.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Delay7.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay7Var.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Delay8.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay8Var.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Delay9.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay9Var.get(), PickleInst[GetTaskID()])  # Save

        if Phase == 1:  # Wait for starting of task
            if Phase1_Init == 0:
                PutPreTaskButton()
                mStatusVar = StringVar(MainWindowRoot)
                mStatus = ttk.Label(MainWindowRightFrame, textvariable=mStatusVar)
                mStatus.place(x=10, y=0)
                mOngoingResultVar = StringVar(MainWindowRoot)
                LearningPhase = 0  # Phase of task, 0:Acquisition, 1:DelayedTask
                SessionDelayID = int(StartSessionVar.get())  # Assign delay ID (0-9)
                if SessionDelayID > 0:  # If session is started from middle
                    LearningPhase = 1  # Phase of task, 0:Acquisition, 1:DelayedTask
                ThClearDay = 0  # Number of stream days where criteria threshold is achieved
                NumOfDelayID = 1
                for i in range(9):
                    if i == 1:
                        if Delay1Var.get() != '':  # If delay is designated
                            NumOfDelayID += 1
                        if Delay1Var.get() == '':  # If delay is not designated
                            break
                    if i == 2:
                        if Delay2Var.get() != '':  # If delay is designated
                            NumOfDelayID += 1
                        if Delay2Var.get() == '':  # If delay is not designated
                            break
                    if i == 3:
                        if Delay3Var.get() != '':  # If delay is designated
                            NumOfDelayID += 1
                        if Delay3Var.get() == '':  # If delay is not designated
                            break
                    if i == 4:
                        if Delay4Var.get() != '':  # If delay is designated
                            NumOfDelayID += 1
                        if Delay4Var.get() == '':  # If delay is not designated
                            break
                    if i == 5:
                        if Delay5Var.get() != '':  # If delay is designated
                            NumOfDelayID += 1
                        if Delay5Var.get() == '':  # If delay is not designated
                            break
                    if i == 6:
                        if Delay6Var.get() != '':  # If delay is designated
                            NumOfDelayID += 1
                        if Delay6Var.get() == '':  # If delay is not designated
                            break
                    if i == 7:
                        if Delay7Var.get() != '':  # If delay is designated
                            NumOfDelayID += 1
                        if Delay7Var.get() == '':  # If delay is not designated
                            break
                    if i == 8:
                        if Delay8Var.get() != '':  # If delay is designated
                            NumOfDelayID += 1
                        if Delay8Var.get() == '':  # If delay is not designated
                            break
                    if i == 9:
                        if Delay9Var.get() != '':  # If delay is designated
                            NumOfDelayID += 1
                        if Delay9Var.get() == '':  # If delay is not designated
                            break
                print('Num of delays: ' + str(NumOfDelayID))

                Phase1_Init = 1
            mStatusVar.set('DNMTP/DMTP task (' + str(GetTaskID()) + ')    Waiting...')
            if IsStartTime() == 1:  # If task start time is arrived
                StartNow()
        if Phase == 2:  # During task
            if Phase2_Init == 0:  # Initialization of the task
                PutEndTaskNowButton()

                mStatusVar.set(
                    'DNMTP/DMTP task (' + str(GetTaskID()) + ')    Start time ' + str(TaskStartedMonth) + '/' + str(TaskStartedDay) + ' ' + str(TaskStartedHour) + ':' + str(TaskStartedMinute) + '    Running')
                mOngoingResult = ttk.Label(MainWindowRightFrame, textvariable=mOngoingResultVar)
                mOngoingResult.place(x=10, y=18)
                ResultStringA = ''
                ResultStringB = ''
                TotalCorrectRate = 0.0

                # Convert StringVars of parameters into integer or normal string to use in the following
                MaxCorrectNum = int(MaxCorrectNumVar.get())
                MaxTrialNum = int(MaxTrialNumVar.get())
                TimeLimit = float(TimeLimitVar.get())
                PunishDur = float(PunishDurVar.get())
                LickDur = float(LickDurVar.get())
                Iti = float(ItiVar.get())
                AwsOn = AwsOnVar.get()
                DelayAllowFactor = float(DelayAllowFactorVar.get())
                RateTh = float(RateThVar.get())
                DayTh = int(DayThVar.get())
                StartSession = int(StartSessionVar.get())
                Seed = int(SeedVar.get())
                NextTask = int(NextTaskVar.get())
                TaskType = TaskTypeVar.get()
                WaterCueType = WaterCueTypeVar.get()
                PunishWithLight = PunishWithLightVar.get()

                PresetDelay = [0 for i in range(10)]
                if Delay0Var.get().isdigit():  # Check whether the string is digit
                    PresetDelay[0] = int(Delay0Var.get())
                if Delay1Var.get().isdigit():  # Check whether the string is digit
                    PresetDelay[1] = int(Delay1Var.get())
                if Delay2Var.get().isdigit():  # Check whether the string is digit
                    PresetDelay[2] = int(Delay2Var.get())
                if Delay3Var.get().isdigit():  # Check whether the string is digit
                    PresetDelay[3] = int(Delay3Var.get())
                if Delay4Var.get().isdigit():  # Check whether the string is digit
                    PresetDelay[4] = int(Delay4Var.get())
                if Delay5Var.get().isdigit():  # Check whether the string is digit
                    PresetDelay[5] = int(Delay5Var.get())
                if Delay6Var.get().isdigit():  # Check whether the string is digit
                    PresetDelay[6] = int(Delay6Var.get())
                if Delay7Var.get().isdigit():  # Check whether the string is digit
                    PresetDelay[7] = int(Delay7Var.get())
                if Delay8Var.get().isdigit():  # Check whether the string is digit
                    PresetDelay[8] = int(Delay8Var.get())
                if Delay9Var.get().isdigit():  # Check whether the string is digit
                    PresetDelay[9] = int(Delay9Var.get())

                if SessionDelayID == 0:
                    DelayA = PresetDelay[SessionDelayID]
                    DelayB = PresetDelay[SessionDelayID]
                if SessionDelayID > 0:
                    DelayA = PresetDelay[SessionDelayID - 1]
                    DelayB = PresetDelay[SessionDelayID]

                StartLickRecording()
                RoofLightOff()
                InfraredLightOn()
                if WaterCueType == 'Normal':
                    DigitalOutOn(10)
                if WaterCueType == 'Blink':
                    DigitalOutBlinkOn(10)
                ServoPosInside(3)

                #CreateNormalPanel(1)  #
                #CreateNormalPanel(2)


                # Declar local variables for this task
                CurrTrialNum = -1
                TotalCorrectNum = 0
                TrialNum = [0 for i in range(2)]
                CorrectNum = [0 for i in range(2)]
                IncorrectNum = [0 for i in range(2)]
                CorrectRate = [0 for i in range(2)]
                ValidCorrectNum = 0  # Correct touch num which have done within the designated delay
                ValidIncorrectNum = 0
                ValidTouchNum = 0
                ValidCorrectRate = 0  # Correct rate which have done within the designated delay
                TouchHistory = [[-1 for i in range(5)] for j in
                    range(MaxTrialNum)]  # Keeps history of touch results and time of touching (For valid trial selection) p0:CorrectPanelID p1:DelayStartTime p2:DelayEndTime p3:Result p4:DelayRand
                DelayHistory = [-1 for i in range(MaxTrialNum)]  # Keeps delay history
                ValidString = ['', '']
                TaskDur = 0

                LightCycleControlOff()
                DoneCorrectResponse = 1
                NowDrinking = 0
                AWS_Latency = 20
                StartRecording()  # Start camera capturing and sending of TTL
                print('Seed: ' + str(Seed))
                random.seed(Seed)

                Timer_Start(5)  # Task time limit timer start
                Phase2 = 8
                Phase2_Init = 1

                Writer_TouchEventTxt = open(
                    Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.txt",
                    'w')  # Initialize the text exporter
                Writer_TouchEventCsv = open(
                    Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.csv",
                    'w')  # Initialize the text exporter
                Writer_TouchEventTxt.write('TrialNum\tResult\tPanel\tyyyy/mm/dd\th:m\ts\tDelay(s)\tDelay type\n')  # Write item name
                print("Task #" + str(GetTaskID()) + " is started at " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(
                    GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

            if Phase2 == 0:  # Initiation of new trial
                TaskDur = Timer_GetSec(5)
                DoneCorrectResponse = 0
                SamplePanelID = int(random.random() * 2)  # Determine which position is correct at random
                if SamplePanelID == 1:
                    SamplePanelID = 2
                print('Trial: ' + str(CurrTrialNum))
                Trg = 0
                if CurrTrialNum <= 1:
                    TouchHistory[CurrTrialNum][0] = SamplePanelID
                if CurrTrialNum > 1:
                    if SamplePanelID == TouchHistory[CurrTrialNum - 1][0] and SamplePanelID == TouchHistory[CurrTrialNum - 2][0]:  # If Correct position is same as previous and pre-previous position
                        if SamplePanelID == 0:
                            SamplePanelID = 2  # Change correct position to the opposite side
                            Trg = 1
                        if SamplePanelID == 2 and Trg == 0:
                            SamplePanelID = 0  # Change correct position to the opposite side
                TouchHistory[CurrTrialNum][0] = SamplePanelID
                if SamplePanelID == 0:
                    CreateBlinkPanel(0)
                    ShowPanel(0)
                if SamplePanelID == 2:
                    CreateBlinkPanel(2)
                    ShowPanel(2)
                Writer_TouchEventTxt.write(
                    str(CurrTrialNum + 1) + '\tCueStart\t' + str(SamplePanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(
                        TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                Writer_TouchEventCsv.write(
                    str(CurrTrialNum + 1) + ',0,' + str(SamplePanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(
                        TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                Timer_Start(0)  # Start the latency timer
                Phase2 = 1

            if Phase2 == 1:  # Sample panel presentation phase
                TouchedPanelID = DetectRoiNosepoke()  # Check which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID == SamplePanelID:  # If mouse touches CORRECT panel
                    DoneCorrectResponse = 1

                    NowDrinking = 0
                    Writer_TouchEventTxt.write(
                        str(CurrTrialNum + 1) + '\tCueCorrectTouch\t' + str(SamplePanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(
                            TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                    Writer_TouchEventCsv.write(
                        str(CurrTrialNum + 1) + ',1,' + str(SamplePanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(
                            TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                    HidePanel(0)
                    HidePanel(2)
                    Timer_End(0)

                    DelayRand = int(random.random() * 2)
                    Trg = 0
                    if CurrTrialNum > 1:
                        if DelayRand == DelayHistory[CurrTrialNum - 1] and DelayRand == DelayHistory[CurrTrialNum - 2]:  # If Correct position is same as previous and pre-previous position
                            if DelayRand == 0:
                                DelayRand = 1  # Change correct position to the opposite side
                                Trg = 1
                            if DelayRand == 1 and Trg == 0:
                                DelayRand = 0  # Change correct position to the opposite side
                    DelayHistory[CurrTrialNum] = DelayRand  # Enter to the history
                    if DelayRand == 0:
                        DelayDur = DelayA  # If this trial is DelayA
                    if DelayRand == 1:
                        DelayDur = DelayB  # If this trial is DelayB
                    AllowedDelay = 10 + (DelayDur * DelayAllowFactor / 100)  # Caliculate threshold for data selection
                    # print(AllowedDelay)
                    Phase2 = 2  # Go to interval
                    Timer_Start(0)

                if Timer_GetSec(5) >= TimeLimit * 60:  # If time limit is exceeded
                    TaskDur = Timer_GetSec(5)
                    Timer_End(5)
                    Phase2 = 12

            if Phase2 == 2:  # Interval between sample touch and 1st center presentation
                # print(Timer_GetSec(0))
                if Timer_GetSec(0) >= 1:
                    CreateNormalPanel(1)
                    ShowPanel(1)  # Show 1st center panel
                    Phase2 = 3

            if Phase2 == 3:  # 1st center panel presentation phase
                TouchedPanelID = DetectRoiNosepoke()  # Check which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID == 1:  # If mouse touches 1st center panel
                    DoneCorrectResponse = 1

                    NowDrinking = 0
                    TouchHistory[CurrTrialNum][1] = (TimeNow.day * 60 * 60 * 24) + (TimeNow.hour * 60 * 60) + (TimeNow.minute * 60) + TimeNow.second
                    Writer_TouchEventTxt.write(
                        str(CurrTrialNum + 1) + '\t1stCenterCorrectTouch\t' + str(TouchedPanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(
                            TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                    Writer_TouchEventCsv.write(
                        str(CurrTrialNum + 1) + ',2,' + str(TouchedPanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(
                            TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                    HidePanel(1)
                    Timer_End(0)
                    Phase2 = 4  # Start reward phase
                    Timer_Start(0)
                if Timer_GetSec(5) >= TimeLimit * 60:  # If time limit is exceeded
                    TaskDur = Timer_GetSec(5)
                    Timer_End(5)
                    Phase2 = 12

            if Phase2 == 4:  # Interval between sample touch and 1st center presentation
                if Timer_GetSec(0) >= DelayDur:
                    CreateNormalPanel(1)
                    ShowPanel(1)  # Show 1st center panel
                    Phase2 = 5

            if Phase2 == 5:  # 2nd center panel presentation phase
                TouchedPanelID = DetectRoiNosepoke()  # Check which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID == 1:  # If mouse touches 1st center panel
                    DoneCorrectResponse = 1

                    NowDrinking = 0
                    Writer_TouchEventTxt.write(
                        str(CurrTrialNum + 1) + '\t2ndCenterCorrectTouch\t' + str(TouchedPanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(
                            TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file

                    Writer_TouchEventCsv.write(
                        str(CurrTrialNum + 1) + ',3,' + str(TouchedPanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(
                            TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                    HidePanel(1)
                    Timer_End(0)
                    Phase2 = 6  # Start reward phase
                    Timer_Start(0)
                if Timer_GetSec(5) >= TimeLimit * 60:  # If time limit is exceeded
                    TaskDur = Timer_GetSec(5)
                    Timer_End(5)
                    Phase2 = 12

            if Phase2 == 6:  # Interval between sample touch and 1st center presentation
                if Timer_GetSec(0) >= 1:
                    if SamplePanelID == 0:
                        if TaskType == 'DNMTP1':
                            CreateNormalPanel(2)
                            ShowPanel(2)  #
                        if TaskType == 'DMTP1':
                            CreateNormalPanel(0)
                            ShowPanel(0)  #
                        if TaskType == 'DNMTP2' or TaskType == 'DMTP2':
                            CreateNormalPanel(0)
                            CreateNormalPanel(2)
                            ShowPanel(0)  #
                            ShowPanel(2)  #
                    if SamplePanelID == 2:
                        if TaskType == 'DNMTP1':
                            CreateNormalPanel(0)
                            ShowPanel(0)  #
                        if TaskType == 'DMTP1':
                            CreateNormalPanel(2)
                            ShowPanel(2)  #
                        if TaskType == 'DNMTP2' or TaskType == 'DMTP2':
                            CreateNormalPanel(0)
                            CreateNormalPanel(2)
                            ShowPanel(0)  #
                            ShowPanel(2)  #
                    Phase2 = 7

            if Phase2 == 7:  # Choice phase
                TouchedPanelID = DetectRoiNosepoke()  # Check which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID != -1 and TouchedPanelID != 19:
                    TouchResult = 0
                    if TaskType == 'DMTP1' or TaskType == 'DMTP2':
                        if TouchedPanelID == SamplePanelID:  # If mouse touches same position with the sample phase
                            TouchResult = 1  # Correct
                        if TouchedPanelID != SamplePanelID and TouchedPanelID != 1:  # If mouse touches opposite position to the sample phase
                            TouchResult = -1  # Wrong
                    if TaskType == 'DNMTP1' or TaskType == 'DNMTP2':
                        if TouchedPanelID != SamplePanelID and TouchedPanelID != 1:  # If mouse touches opposite position to the sample phase
                            TouchResult = 1  # Correct

                        if TouchedPanelID == SamplePanelID:  # If mouse touches same position with the sample phase
                            TouchResult = -1  # Wrong
                    if TouchResult == 1:  # If mouse touches correct panel
                        DoneCorrectResponse = 1
                        NowDrinking = 0
                        TouchHistory[CurrTrialNum][2] = (TimeNow.day * 60 * 60 * 24) + (TimeNow.hour * 60 * 60) + (TimeNow.minute * 60) + TimeNow.second
                        TouchHistory[CurrTrialNum][3] = 1
                        TouchHistory[CurrTrialNum][4] = DelayRand
                        TrialNum[DelayRand] += 1
                        CorrectNum[DelayRand] += 1  # Increase the number of correct respon
                        TotalCorrectNum += 1
                        CorrectRate[DelayRand] = round(CorrectNum[DelayRand] * 100.0 / TrialNum[DelayRand], 2)
                        Writer_TouchEventTxt.write(
                            str(CurrTrialNum + 1) + '\tTestCorrectTouch\t' + str(TouchedPanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(
                                TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\t" + str(DelayDur) + "\t" + str(
                                DelayRand) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(
                            str(CurrTrialNum + 1) + ',4,' + str(TouchedPanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(
                                TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "," + str(DelayDur) + "," + str(
                                DelayRand) + "\n")  # Write the response on the csv file
                        HidePanel(0)
                        HidePanel(2)
                        Timer_End(0)
                        if WaterCueType == 'Normal':
                            DigitalOutOn(10)
                        if WaterCueType == 'Blink':
                            DigitalOutBlinkOn(10)
                        ServoPosInside(3)
                        Phase2 = 8  # Go to reward phase

                    if TouchResult == -1:  # If mouse touches wrong panel
                        DoneCorrectResponse = 0
                        NowDrinking = 0
                        TouchHistory[CurrTrialNum][2] = (TimeNow.day * 60 * 60 * 24) + (TimeNow.hour * 60 * 60) + (TimeNow.minute * 60) + TimeNow.second
                        TouchHistory[CurrTrialNum][3] = 0
                        TouchHistory[CurrTrialNum][4] = DelayRand
                        TrialNum[DelayRand] += 1
                        IncorrectNum[DelayRand] += 1  # Increase the number of correct response
                        CorrectRate[DelayRand] = round(CorrectNum[DelayRand] * 100.0 / TrialNum[DelayRand], 2)
                        Writer_TouchEventTxt.write(
                            str(CurrTrialNum + 1) + '\tTestIncorrectTouch\t' + str(TouchedPanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(
                                TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\t" + str(DelayDur) + "\t" + str(
                                DelayRand) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(
                            str(CurrTrialNum + 1) + ',5,' + str(TouchedPanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(
                                TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "," + str(DelayDur) + "," + str(
                                DelayRand) + "\n")  # Write the response on the csv file
                        HidePanel(0)
                        HidePanel(2)
                        Timer_End(0)
                        if PunishWithLight == 'ON':
                            RoofLightOn()  # Turn on roof light
                        ServoPosOutside(3)
                        Phase2 = 8  # Start reward phase
                        Timer_Start(0)

                if Timer_GetSec(5) >= TimeLimit * 60:  # If time limit is exceeded
                    TaskDur = Timer_GetSec(5)
                    Timer_End(5)
                    Phase2 = 12

            if Phase2 == 8:
                for i2 in range(2):
                    # Caliculate valid score
                    ValidTouchNum = 0
                    ValidCorrectNum = 0
                    ValidIncorrectNum = 0
                    for i in range(CurrTrialNum + 1):  # Loop for trials
                        if TouchHistory[i][2] == -1:  # If this trial is not completed
                            break
                        if TouchHistory[i][4] == i2:  # If this trial is completed
                            if TouchHistory[i][2] != -1:  # If this trial is completed
                                ActualDelay = TouchHistory[i][2] - TouchHistory[i][1]
                                if ActualDelay <= AllowedDelay:
                                    ValidTouchNum += 1
                                    if TouchHistory[i][3] == 1:
                                        ValidCorrectNum += 1
                                    if TouchHistory[i][3] == 0:
                                        ValidIncorrectNum += 1
                    if ValidTouchNum > 0:
                        ValidCorrectRate = round(ValidCorrectNum / ValidTouchNum * 100, 1)
                        ValidString[i2] = '  /  ValidCorrect:' + str(ValidCorrectNum) + '  ValidWrong:' + str(ValidIncorrectNum) + '  ValidTotalNum:' + str(ValidTouchNum) + '  ValidCorrect:' + str(
                            ValidCorrectRate) + '%'
                ResultStringA = 'Delay ' + str(DelayA) + 's : CorrectNum:' + str(CorrectNum[0]) + '  IncorrectNum:' + str(IncorrectNum[0]) + '  TrialNum:' + str(TrialNum[0]) + '  Correct:' + str(
                    CorrectRate[0]) + '%' + ValidString[0]
                ResultStringB = 'Delay ' + str(DelayB) + 's : CorrectNum:' + str(CorrectNum[1]) + '  IncorrectNum:' + str(IncorrectNum[1]) + '  TrialNum:' + str(TrialNum[1]) + '  Correct:' + str(
                    CorrectRate[1]) + '%' + ValidString[1]
                mOngoingResultVar.set(ResultStringA + '\n' + ResultStringB)
                if DoneCorrectResponse == 1:
                    Phase2 = 9
                if DoneCorrectResponse == 0:
                    Phase2 = 10

            if Phase2 == 9:  # Reward phase
                if DetectRoiNosepoke() == 19 and NowDrinking == 0:  # If the mouse initiates nose poke
                    NowDrinking = 1
                    Timer_Start(0)  # Start lick timer
                if NowDrinking == 1:
                    if DoneCorrectResponse == 1 and Timer_GetSec(0) >= LickDur:  # If lick time exceed the designated time
                        Timer_End(0)  # End lick timer
                        ServoPosMiddle(3)  # Move water nozzle to the intermediate position
                        DigitalOutOff(10)
                        NowDrinking = 0
                        Timer_Start(0)  # Start ITI timer
                        Phase2 = 11  # Go to ITI

            if Phase2 == 10:  # Punishment phase
                if Timer_GetSec(0) >= PunishDur:  # If punishment time is passed
                    RoofLightOff()
                    ServoPosMiddle(3)  # Move water nozzle to the intermediate position
                    Timer_End(0)  # End punishment timer1
                    Timer_Start(0)  # Start ITI timer
                    Phase2 = 11  # Go to ITI

            if Phase2 == 11:  # ITI
                if Timer_GetSec(0) >= Iti:  # If ITI is passed
                    if TotalCorrectNum >= MaxCorrectNum or CurrTrialNum >= MaxTrialNum - 1:  # If mouse achieved criteria of finishing the task
                        Timer_End(5)
                        ServoPosMiddle(3)
                        DigitalOutOff(10)
                        Timer_Start(0)  # Timer for interval between task and arbitary water supply is started
                        Phase2 = 12  # Go to the AWS
                    else:
                        CurrTrialNum += 1
                        Phase2 = 0  # Go to the next trial

            if Phase2 == 12:  # End session
                HidePanel(0)
                HidePanel(1)
                HidePanel(2)
                HidePanel(3)
                HidePanel(4)
                if TotalCorrectNum < MaxCorrectNum and AwsOn == 'ON':  # If mouse didn't achieved the max correct response
                    Timer_Start(0)
                    Phase2 = 13
                if TotalCorrectNum == MaxCorrectNum or AwsOn == 'OFF':  # If mouse achieved the max correct response
                    Phase2 = -1

            if Phase2 == 13:  # Wait until arbitary water suuply is started
                if Timer_GetSec(0) >= 20:  # If the interval is past 20
                    Timer_End(0)
                    ArbitaryWaterSupplyDur = (MaxCorrectNum - TotalCorrectNum) * LickDur * 1000  # Caliculate duration of complement water supply
                    if WaterCueType == 'Normal':
                        StartArbitaryWaterSupply(3,10,0,ArbitaryWaterSupplyDur) # Start complement water supply
                    if WaterCueType == 'Blink':
                        StartArbitaryWaterSupply(3,10,1,ArbitaryWaterSupplyDur) # Start complement water supply
                    print("AWSstart")
                    Phase2 = 14
            if Phase2 == 14:
                if GetArbitaryWaterSupplyStat() == 1:  # If complement water supply is finished
                    Phase2 = -1

            if Phase2 == -1 or GetEndTaskNowButtonStat() == 1:  # Task finish phase
                LightCycleControlOn()
                ServoPosMiddle(3)
                DeleteAllPanel()
                InfraredLightOff()
                if GetRecordingStat() == 1:
                    SetEndRecordingTimer(60)

                if CurrTrialNum > 0:
                    Writer_TouchEventTxt.write(ResultStringA + '\n' + ResultStringB + '\n')  # Summary of results
                Writer_TouchEventTxt.write('SessionStartTime: ' + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()) + "\n")
                Writer_TouchEventTxt.write('SessionEndTime: ' + str(TimeNow.month) + '/' + str(TimeNow.day) + ' ' + str(TimeNow.hour) + ':' + str(TimeNow.minute) + ':' + str(TimeNow.second + (TimeNow.microsecond // 1000) / 1000) + "\n")
                Writer_TouchEventTxt.write('TaskDuration(sec): ' + str(GetTaskID()) + "\n")
                Writer_TouchEventTxt.write('DelayA: ' + str(DelayA) + " sec\n")
                Writer_TouchEventTxt.write('DelayB: ' + str(DelayB) + " sec\n")
                Writer_TouchEventTxt.write('MaxCorrectNum: ' + str(MaxCorrectNum) + "\n")
                Writer_TouchEventTxt.write('MaxTrialNum: ' + str(MaxTrialNum) + "\n")
                Writer_TouchEventTxt.write('TimeLimit: ' + str(TimeLimit) + " min\n")
                Writer_TouchEventTxt.write('PunishDur: ' + str(PunishDur) + " sec\n")
                Writer_TouchEventTxt.write('LickDur: ' + str(LickDur) + " sec\n")
                Writer_TouchEventTxt.write('Iti: ' + str(Iti) + " sec\n")
                Writer_TouchEventTxt.write('ValidDelay%: ' + str(DelayAllowFactor) + " %\n")
                Writer_TouchEventTxt.write('RateTh: ' + str(RateTh) + " %\n")
                Writer_TouchEventTxt.write('DayTh: ' + str(DayTh) + " day\n")
                Writer_TouchEventTxt.write('Seed: ' + str(Seed) + "\n")
                Writer_TouchEventTxt.write('NextTask: ' + str(NextTask) + "\n")
                Writer_TouchEventTxt.write('TaskType: ' + str(TaskType) + "\n")
                Writer_TouchEventTxt.write('WaterCueType: ' + str(WaterCueType) + "\n")
                Writer_TouchEventTxt.write('PunishLight: ' + str(PunishWithLight) + "\n")
                Writer_TouchEventTxt.write('RecordFPS: ' + str(GetRecordFps()) + "\n")
                Writer_TouchEventTxt.write('AWS: ' + AwsOn + "\n")
                Writer_TouchEventTxt.write('AWS_Latency: ' + str(AWS_Latency) + "\n")
                Writer_TouchEventTxt.write(GetRoiSensitivity() + "\n")
                Writer_TouchEventTxt.write(GetServoAngle() + "\n")

                Writer_TouchEventTxt.close()
                Writer_TouchEventCsv.close()
                EndLickRecording()

                SendMail(DeviceNameVar.get() + ' finished task ' + str(GetTaskID()) + '.' + ResultStringA + ';  ' + ResultStringB + ';  Dur:' + str(round(Timer_GetSec(5) / 60, 1)) + ' min',
                    'Task is finished.')

                if IsHousingAnalysis == 1:  #
                    SeedVar.set(Seed + 1)
                    # Update condition of experiment
                    if LearningPhase == 0:  # If it is acquisition phase
                        TotalCorrectRate = 0.0
                        if TrialNum[0]!=0 or TrialNum[1]!=0:
                            TotalCorrectRate = (CorrectNum[0] + CorrectNum[1]) * 100 / (TrialNum[0] + TrialNum[1])

                        #if CurrTrialNum != 0:
                        if TotalCorrectRate >= RateTh:  # If correct rate exceeded the criteria
                            ThClearDay += 1  # Increase the criteria counter
                            print("Current cleared stream days:" + str(ThClearDay))
                            if ThClearDay >= DayTh:  # If acquisition is completed
                                LearningPhase = 1  # Go to the delayed phase
                                print("Delayed phase is started")
                        if TotalCorrectRate < RateTh:  # If correct rate belowed the criteria
                            ThClearDay = 0  # Reset the criteria counter
                    if LearningPhase == 1:  # If it is delayed phase
                        SessionDelayID += 1  # Change delay
                        if SessionDelayID == 1:
                            print("Next delay is " + Delay0Var.get() + " sec / " + Delay1Var.get() + " sec")
                        if SessionDelayID == 2:
                            print("Next delay is " + Delay1Var.get() + " sec / " + Delay2Var.get() + " sec")
                        if SessionDelayID == 3:
                            print("Next delay is " + Delay2Var.get() + " sec / " + Delay3Var.get() + " sec")
                        if SessionDelayID == 4:
                            print("Next delay is " + Delay3Var.get() + " sec / " + Delay4Var.get() + " sec")
                        if SessionDelayID == 5:
                            print("Next delay is " + Delay4Var.get() + " sec / " + Delay5Var.get() + " sec")
                        if SessionDelayID == 6:
                            print("Next delay is " + Delay5Var.get() + " sec / " + Delay6Var.get() + " sec")
                        if SessionDelayID == 7:
                            print("Next delay is " + Delay6Var.get() + " sec / " + Delay7Var.get() + " sec")
                        if SessionDelayID == 8:
                            print("Next delay is " + Delay7Var.get() + " sec / " + Delay8Var.get() + " sec")
                        if SessionDelayID == 9:
                            print("Next delay is " + Delay8Var.get() + " sec / " + Delay9Var.get() + " sec")
                        if Phase2 == -1:
                            if SessionDelayID > NumOfDelayID - 1:  # If the last delayed session is finished (This task is completed)
                                print(NumOfDelayID)
                                SwitchTask(NextTask)  # Onset task switch trigger
                                print("Task is switched to task#" + str(NextTask) + "  " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(
                                    GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

                if IsHousingAnalysis == 0:
                    RoofLightOn()

                Phase = 1  # Go back to the task-waiting phase
                Phase2 = 0
                Phase2_Init = 0
            SetDispVariable(0, 'Phase2', str(Phase2))  # Display "Phase2" value on the main window
    return

def Task7():    #DNMTP
    global Phase
    Phase0_Init = 0
    Phase1_Init = 0
    Phase2_Init = 0
    while EndFlag == 0:
        OperantHouseUpdate()
        if GetBackButtonStat()==1:    # If "Back" button is clicked
            break   # Back to the task select phase
        if Phase == 0:  # Parameter inputs
            if Phase0_Init == 0:
                # Make GUI for the setting of the parameters for this task
                RemoveMainRightWidget()  # Remove task buttons
                PutStartBackButton()  # Put start/back buttons

                ColumnWidth = 10
                Row = 0  # Begin a new line
                Column = 0
                XShift = 0
                XShiftLength = 80
                YShift = 0

                mMaxCorrectNum = ttk.Label(MainWindowRightFrame, text='MaxCorrect', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                MaxCorrectNumVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iMaxCorrectNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxCorrectNumVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mMaxTrialNum = ttk.Label(MainWindowRightFrame, text='MaxTrial', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                MaxTrialNumVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iMaxTrialNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxTrialNumVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mTimeLimit = ttk.Label(MainWindowRightFrame, text='Limit(min)', width=11).grid(row=Row, column=Column, sticky=W)  # Put label
                TimeLimitVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iTimeLimit = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitVar, width=11).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mPunishDur = ttk.Label(MainWindowRightFrame, text='PunishDur(s)', width=12).grid(row=Row, column=Column, sticky=W)  # Put label
                PunishDurVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iPunishDur = ttk.Entry(MainWindowRightFrame, textvariable=PunishDurVar, width=12).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mLickDur = ttk.Label(MainWindowRightFrame, text='LickDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                LickDurVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iLickDur = ttk.Entry(MainWindowRightFrame, textvariable=LickDurVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mIti = ttk.Label(MainWindowRightFrame, text='ITI(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                ItiVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iIti = ttk.Entry(MainWindowRightFrame, textvariable=ItiVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mDelayAllowFactor = ttk.Label(MainWindowRightFrame, text='ValidDelay(%)', width=12).grid(row=Row, column=Column, sticky=W)  # Put label
                DelayAllowFactorVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelayAllowFactor = ttk.Entry(MainWindowRightFrame, textvariable=DelayAllowFactorVar, width=12).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mRateTh = ttk.Label(MainWindowRightFrame, text='RateTh(%)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                RateThVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iRateTh = ttk.Entry(MainWindowRightFrame, textvariable=RateThVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mDayTh = ttk.Label(MainWindowRightFrame, text='DayTh(d)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                DayThVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDayTh = ttk.Entry(MainWindowRightFrame, textvariable=DayThVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mStartSession = ttk.Label(MainWindowRightFrame, text='StartSession', width=12).grid(row=Row, column=Column, sticky=W)  # Put label
                StartSessionVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iStartSession = ttk.Entry(MainWindowRightFrame, textvariable=StartSessionVar, width=12).grid(row=Row + 1, column=Column)  # Place entry field

                Row += 2  # Begin a new line
                Column = 0

                mSeed = ttk.Label(MainWindowRightFrame, text='Seed', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                SeedVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iSeed = ttk.Entry(MainWindowRightFrame, textvariable=SeedVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mNextTask = ttk.Label(MainWindowRightFrame, text='NextTask', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                NextTaskVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iNextTask = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mTaskType = ttk.Label(MainWindowRightFrame, text='TaskType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                TaskTypeVar = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                tTaskType = OptionMenu(MainWindowRightFrame, TaskTypeVar, "DNMTP1", "DNMTP2", "DMTP1", "DMTP2").grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mWaterCueType = ttk.Label(MainWindowRightFrame, text='WaterCue', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                WaterCueTypeVar = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                tWaterCueType = OptionMenu(MainWindowRightFrame, WaterCueTypeVar, "Normal", "Blink").grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mPunishWithLight = ttk.Label(MainWindowRightFrame, text='PunishLight', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                PunishWithLightVar = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                tPunishWithLight = OptionMenu(MainWindowRightFrame, PunishWithLightVar, "ON", "OFF").grid(row=Row + 1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mAwsOn = ttk.Label(MainWindowRightFrame, text='AWS', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                AwsOnVar = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                tAwsOn = OptionMenu(MainWindowRightFrame, AwsOnVar, "ON", "OFF").grid(row=Row + 1, column=Column)  # Place entry field

                Row += 2  # Begin a new line
                Column = 0

                ColumnWidth = 10
                YShift=94
                # mDelay0 = ttk.Label(MainWindowRightFrame, text='Delay0(sec)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                mDelay0 = ttk.Label(MainWindowRightFrame, text='Delay0(sec)', width=ColumnWidth).place(x=XShift, y=YShift)
                Delay0Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                # iDelay0 = ttk.Entry(MainWindowRightFrame, textvariable=Delay0Var, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Place entry field
                iDelay0 = ttk.Entry(MainWindowRightFrame, textvariable=Delay0Var, width=ColumnWidth).place(x=XShift, y=YShift+20)  # Place entry field
                XShift += XShiftLength
                mDelay1 = ttk.Label(MainWindowRightFrame, text='Delay1', width=ColumnWidth).place(x=XShift, y=YShift)  # Put label
                Delay1Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay1 = ttk.Entry(MainWindowRightFrame, textvariable=Delay1Var, width=ColumnWidth).place(x=XShift, y=YShift+20)  # Place entry field
                XShift += XShiftLength
                mDelay2 = ttk.Label(MainWindowRightFrame, text='Delay2', width=ColumnWidth).place(x=XShift, y=YShift)  # Put label
                Delay2Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay2 = ttk.Entry(MainWindowRightFrame, textvariable=Delay2Var, width=ColumnWidth).place(x=XShift, y=YShift+20)  # Place entry field
                XShift += XShiftLength
                mDelay3 = ttk.Label(MainWindowRightFrame, text='Delay3', width=ColumnWidth).place(x=XShift, y=YShift)  # Put label
                Delay3Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay3 = ttk.Entry(MainWindowRightFrame, textvariable=Delay3Var, width=ColumnWidth).place(x=XShift, y=YShift+20)  # Place entry field
                XShift += XShiftLength
                mDelay4 = ttk.Label(MainWindowRightFrame, text='Delay4', width=ColumnWidth).place(x=XShift, y=YShift)  # Put label
                Delay4Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay4 = ttk.Entry(MainWindowRightFrame, textvariable=Delay4Var, width=ColumnWidth).place(x=XShift, y=YShift+20)  # Place entry field
                XShift += XShiftLength
                mDelay5 = ttk.Label(MainWindowRightFrame, text='Delay5', width=ColumnWidth).place(x=XShift, y=YShift)  # Put label
                Delay5Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay5 = ttk.Entry(MainWindowRightFrame, textvariable=Delay5Var, width=ColumnWidth).place(x=XShift, y=YShift+20)  # Place entry field
                XShift += XShiftLength
                mDelay6 = ttk.Label(MainWindowRightFrame, text='Delay6', width=ColumnWidth).place(x=XShift, y=YShift)  # Put label
                Delay6Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay6 = ttk.Entry(MainWindowRightFrame, textvariable=Delay6Var, width=ColumnWidth).place(x=XShift, y=YShift+20)  # Place entry field
                XShift += XShiftLength
                mDelay7 = ttk.Label(MainWindowRightFrame, text='Delay7', width=ColumnWidth).place(x=XShift, y=YShift)  # Put label
                Delay7Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay7 = ttk.Entry(MainWindowRightFrame, textvariable=Delay7Var, width=ColumnWidth).place(x=XShift, y=YShift+20)  # Place entry field
                XShift += XShiftLength
                mDelay8 = ttk.Label(MainWindowRightFrame, text='Delay8', width=ColumnWidth).place(x=XShift, y=YShift)  # Put label
                Delay8Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay8 = ttk.Entry(MainWindowRightFrame, textvariable=Delay8Var, width=ColumnWidth).place(x=XShift, y=YShift+20)  # Place entry field
                XShift += XShiftLength
                mDelay9 = ttk.Label(MainWindowRightFrame, text='Delay9', width=ColumnWidth).place(x=XShift, y=YShift)  # Put label
                Delay9Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay9 = ttk.Entry(MainWindowRightFrame, textvariable=Delay9Var, width=ColumnWidth).place(x=XShift, y=YShift+20)  # Place entry field

                Str = "ParametersForTask" + str(GetTaskID())
                if os.path.exists(Str + '/MaxCorrectNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxCorrectNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxCorrectNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxCorrectNumVar.set(80)  # Default value

                if os.path.exists(Str + '/MaxTrialNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxTrialNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxTrialNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxTrialNumVar.set(999)  # Default value

                if os.path.exists(Str + '/TimeLimit.dat') == True:  # If save file exists
                    with open(Str + '/TimeLimit.dat', 'rb') as PickleInst[GetTaskID()]:
                        TimeLimitVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    TimeLimitVar.set(600)  # Default value

                if os.path.exists(Str + '/PunishDur.dat') == True:  # If save file exists
                    with open(Str + '/PunishDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishDurVar.set(10)  # Default value

                if os.path.exists(Str + '/LickDur.dat') == True:  # If save file exists
                    with open(Str + '/LickDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        LickDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    LickDurVar.set(2)  # Default value

                if os.path.exists(Str + '/Iti.dat') == True:  # If save file exists
                    with open(Str + '/Iti.dat', 'rb') as PickleInst[GetTaskID()]:
                        ItiVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    ItiVar.set(30)  # Default value

                if os.path.exists(Str + '/DelayAllowFactor.dat') == True:  # If save file exists
                    with open(Str + '/DelayAllowFactor.dat', 'rb') as PickleInst[GetTaskID()]:
                        DelayAllowFactorVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    DelayAllowFactorVar.set(130)  # Default value

                if os.path.exists(Str + '/RateTh.dat') == True:  # If save file exists
                    with open(Str + '/RateTh.dat', 'rb') as PickleInst[GetTaskID()]:
                        RateThVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    RateThVar.set(80)  # Default value

                if os.path.exists(Str + '/DayTh.dat') == True:  # If save file exists
                    with open(Str + '/DayTh.dat', 'rb') as PickleInst[GetTaskID()]:
                        DayThVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    DayThVar.set(2)  # Default value

                if os.path.exists(Str + '/StartSession.dat') == True:  # If save file exists
                    with open(Str + '/StartSession.dat', 'rb') as PickleInst[GetTaskID()]:
                        StartSessionVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    StartSessionVar.set(0)  # Default value

                if os.path.exists(Str + '/Seed.dat') == True:  # If save file exists
                    with open(Str + '/Seed.dat', 'rb') as PickleInst[GetTaskID()]:
                        SeedVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    SeedVar.set(0)  # Default value
                if os.path.exists(Str + '/NextTask.dat') == True:  # If save file exists
                    with open(Str + '/NextTask.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskVar.set(6)  # Default value
                if os.path.exists(Str + '/TaskType.dat') == True:  # If save file exists
                    with open(Str + '/TaskType.dat', 'rb') as PickleInst[GetTaskID()]:
                        TaskTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    TaskTypeVar.set('DNMTP1')  # Default value

                if os.path.exists(Str + '/WaterCueType.dat') == True:  # If save file exists
                    with open(Str + '/WaterCueType.dat', 'rb') as PickleInst[GetTaskID()]:
                        WaterCueTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    WaterCueTypeVar.set('Normal')  # Default value

                if os.path.exists(Str + '/PunishWithLight.dat') == True:  # If save file exists
                    with open(Str + '/PunishWithLight.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishWithLightVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishWithLightVar.set('ON')  # Default value

                if os.path.exists(Str + '/Delay0.dat') == True:  # If save file exists
                    with open(Str + '/Delay0.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay0Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay0Var.set('1')  # Default value
                if os.path.exists(Str + '/AwsOn.dat') == True:  # If save file exists
                    with open(Str + '/AwsOn.dat', 'rb') as PickleInst[GetTaskID()]:
                        AwsOnVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    AwsOnVar.set('OFF')  # Default value
                if os.path.exists(Str + '/Delay1.dat') == True:  # If save file exists
                    with open(Str + '/Delay1.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay1Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay1Var.set('')  # Default value
                if os.path.exists(Str + '/Delay2.dat') == True:  # If save file exists
                    with open(Str + '/Delay2.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay2Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay2Var.set('')  # Default value
                if os.path.exists(Str + '/Delay3.dat') == True:  # If save file exists
                    with open(Str + '/Delay3.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay3Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay3Var.set('')  # Default value
                if os.path.exists(Str + '/Delay4.dat') == True:  # If save file exists
                    with open(Str + '/Delay4.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay4Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay4Var.set('')  # Default value
                if os.path.exists(Str + '/Delay5.dat') == True:  # If save file exists
                    with open(Str + '/Delay5.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay5Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay5Var.set('')  # Default value
                if os.path.exists(Str + '/Delay6.dat') == True:  # If save file exists
                    with open(Str + '/Delay6.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay6Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay6Var.set('')  # Default value
                if os.path.exists(Str + '/Delay7.dat') == True:  # If save file exists
                    with open(Str + '/Delay7.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay7Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay7Var.set('')  # Default value
                if os.path.exists(Str + '/Delay8.dat') == True:  # If save file exists
                    with open(Str + '/Delay8.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay8Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay8Var.set('')  # Default value
                if os.path.exists(Str + '/Delay9.dat') == True:  # If save file exists
                    with open(Str + '/Delay9.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay9Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay9Var.set('')  # Default value

                RemoveAllRoiGui()
                PutRoiGui(0, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(1, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(2, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(19, 0, 0, 1)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)

                RemoveAllDigitalOutGui()
                PutDigitalOutGui(10)
                PutDigitalOutGui(12)
                PutDigitalOutGui(13)

                RemoveAllServoGui()
                PutServoGui(3)
                Phase0_Init = 1

        if GetSaveTrgStat() == 1:  # If save trigger is on
            # Parameters of each task are saved into different folder
            Str = "ParametersForTask" + str(GetTaskID())  # Path to the folder for saving of parameters
            if os.path.exists(Str) == False:  # If folder for saving parameters is not exist
                os.mkdir(Str)  # Make folder for saving
            with open(Str + '/MaxCorrectNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxCorrectNumVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/MaxTrialNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxTrialNumVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/TimeLimit.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TimeLimitVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/PunishDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishDurVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/LickDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(LickDurVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Iti.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(ItiVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/DelayAllowFactor.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(DelayAllowFactorVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/RateTh.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(RateThVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/DayTh.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(DayThVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/StartSession.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(StartSessionVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Seed.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(SeedVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/NextTask.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/TaskType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TaskTypeVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/WaterCueType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(WaterCueTypeVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/PunishWithLight.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishWithLightVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/AwsOn.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(AwsOnVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Delay0.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay0Var.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Delay1.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay1Var.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Delay2.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay2Var.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Delay3.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay3Var.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Delay4.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay4Var.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Delay5.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay5Var.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Delay6.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay6Var.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Delay7.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay7Var.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Delay8.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay8Var.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Delay9.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay9Var.get(), PickleInst[GetTaskID()])  # Save

        if Phase == 1:  # Wait for starting of task
            if Phase1_Init == 0:
                PutPreTaskButton()
                mStatusVar = StringVar(MainWindowRoot)
                mStatus = ttk.Label(MainWindowRightFrame, textvariable=mStatusVar)
                mStatus.place(x=10, y=0)
                mOngoingResultVar = StringVar(MainWindowRoot)
                LearningPhase = 0  # Phase of task, 0:Acquisition, 1:DelayedTask
                SessionDelayID = int(StartSessionVar.get())  # Assign delay ID (0-9)
                if SessionDelayID > 0:  # If session is started from middle
                    LearningPhase = 1  # Phase of task, 0:Acquisition, 1:DelayedTask
                ThClearDay = 0  # Number of stream days where criteria threshold is achieved
                NumOfDelayID = 1
                for i in range(9):
                    if i == 1:
                        if Delay1Var.get() != '':  # If delay is designated
                            NumOfDelayID += 1
                        if Delay1Var.get() == '':  # If delay is not designated
                            break
                    if i == 2:
                        if Delay2Var.get() != '':  # If delay is designated
                            NumOfDelayID += 1
                        if Delay2Var.get() == '':  # If delay is not designated
                            break
                    if i == 3:
                        if Delay3Var.get() != '':  # If delay is designated
                            NumOfDelayID += 1
                        if Delay3Var.get() == '':  # If delay is not designated
                            break
                    if i == 4:
                        if Delay4Var.get() != '':  # If delay is designated
                            NumOfDelayID += 1
                        if Delay4Var.get() == '':  # If delay is not designated
                            break
                    if i == 5:
                        if Delay5Var.get() != '':  # If delay is designated
                            NumOfDelayID += 1
                        if Delay5Var.get() == '':  # If delay is not designated
                            break
                    if i == 6:
                        if Delay6Var.get() != '':  # If delay is designated
                            NumOfDelayID += 1
                        if Delay6Var.get() == '':  # If delay is not designated
                            break
                    if i == 7:
                        if Delay7Var.get() != '':  # If delay is designated
                            NumOfDelayID += 1
                        if Delay7Var.get() == '':  # If delay is not designated
                            break
                    if i == 8:
                        if Delay8Var.get() != '':  # If delay is designated
                            NumOfDelayID += 1
                        if Delay8Var.get() == '':  # If delay is not designated
                            break
                    if i == 9:
                        if Delay9Var.get() != '':  # If delay is designated
                            NumOfDelayID += 1
                        if Delay9Var.get() == '':  # If delay is not designated
                            break
                print('Num of delays: ' + str(NumOfDelayID))

                Phase1_Init = 1
            mStatusVar.set('DNMTP/DMTP task (' + str(GetTaskID()) + ')    Waiting...')
            if IsStartTime() == 1:  # If task start time is arrived
                StartNow()
        if Phase == 2:  # During task
            if Phase2_Init == 0:  # Initialization of the task
                PutEndTaskNowButton()

                mStatusVar.set(
                    'DNMTP/DMTP task (' + str(GetTaskID()) + ')    Start time ' + str(TaskStartedMonth) + '/' + str(TaskStartedDay) + ' ' + str(TaskStartedHour) + ':' + str(TaskStartedMinute) + '    Running')
                mOngoingResult = ttk.Label(MainWindowRightFrame, textvariable=mOngoingResultVar)
                mOngoingResult.place(x=10, y=18)
                ResultStringA = ''
                ResultStringB = ''
                TotalCorrectRate = 0.0

                # Convert StringVars of parameters into integer or normal string to use in the following
                MaxCorrectNum = int(MaxCorrectNumVar.get())
                MaxTrialNum = int(MaxTrialNumVar.get())
                TimeLimit = float(TimeLimitVar.get())
                PunishDur = float(PunishDurVar.get())
                LickDur = float(LickDurVar.get())
                Iti = float(ItiVar.get())
                AwsOn = AwsOnVar.get()
                DelayAllowFactor = float(DelayAllowFactorVar.get())
                RateTh = float(RateThVar.get())
                DayTh = int(DayThVar.get())
                StartSession = int(StartSessionVar.get())
                Seed = int(SeedVar.get())
                NextTask = int(NextTaskVar.get())
                TaskType = TaskTypeVar.get()
                WaterCueType = WaterCueTypeVar.get()
                PunishWithLight = PunishWithLightVar.get()

                PresetDelay = [0 for i in range(10)]
                if Delay0Var.get().isdigit():  # Check whether the string is digit
                    PresetDelay[0] = int(Delay0Var.get())
                if Delay1Var.get().isdigit():  # Check whether the string is digit
                    PresetDelay[1] = int(Delay1Var.get())
                if Delay2Var.get().isdigit():  # Check whether the string is digit
                    PresetDelay[2] = int(Delay2Var.get())
                if Delay3Var.get().isdigit():  # Check whether the string is digit
                    PresetDelay[3] = int(Delay3Var.get())
                if Delay4Var.get().isdigit():  # Check whether the string is digit
                    PresetDelay[4] = int(Delay4Var.get())
                if Delay5Var.get().isdigit():  # Check whether the string is digit
                    PresetDelay[5] = int(Delay5Var.get())
                if Delay6Var.get().isdigit():  # Check whether the string is digit
                    PresetDelay[6] = int(Delay6Var.get())
                if Delay7Var.get().isdigit():  # Check whether the string is digit
                    PresetDelay[7] = int(Delay7Var.get())
                if Delay8Var.get().isdigit():  # Check whether the string is digit
                    PresetDelay[8] = int(Delay8Var.get())
                if Delay9Var.get().isdigit():  # Check whether the string is digit
                    PresetDelay[9] = int(Delay9Var.get())

                if SessionDelayID == 0:
                    DelayA = PresetDelay[SessionDelayID]
                    DelayB = PresetDelay[SessionDelayID]
                if SessionDelayID > 0:
                    DelayA = PresetDelay[SessionDelayID - 1]
                    DelayB = PresetDelay[SessionDelayID]

                StartLickRecording()
                RoofLightOff()
                InfraredLightOn()
                if WaterCueType == 'Normal':
                    DigitalOutOn(10)
                if WaterCueType == 'Blink':
                    DigitalOutBlinkOn(10)
                ServoPosInside(3)

                #CreateNormalPanel(1)  #
                #CreateNormalPanel(2)


                # Declar local variables for this task
                CurrTrialNum = -1
                TotalCorrectNum = 0
                TrialNum = [0 for i in range(2)]
                CorrectNum = [0 for i in range(2)]
                IncorrectNum = [0 for i in range(2)]
                CorrectRate = [0 for i in range(2)]
                ValidCorrectNum = 0  # Correct touch num which have done within the designated delay
                ValidIncorrectNum = 0
                ValidTouchNum = 0
                ValidCorrectRate = 0  # Correct rate which have done within the designated delay
                TouchHistory = [[-1 for i in range(5)] for j in
                    range(MaxTrialNum)]  # Keeps history of touch results and time of touching (For valid trial selection) p0:CorrectPanelID p1:DelayStartTime p2:DelayEndTime p3:Result p4:DelayRand
                DelayHistory = [-1 for i in range(MaxTrialNum)]  # Keeps delay history
                ValidString = ['', '']
                TaskDur = 0

                LightCycleControlOff()
                DoneCorrectResponse = 1
                NowDrinking = 0
                AWS_Latency = 20
                StartRecording()  # Start camera capturing and sending of TTL
                print('Seed: ' + str(Seed))
                random.seed(Seed)

                Timer_Start(5)  # Task time limit timer start
                Phase2 = 8
                Phase2_Init = 1

                Writer_TouchEventTxt = open(
                    Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.txt",
                    'w')  # Initialize the text exporter
                Writer_TouchEventCsv = open(
                    Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.csv",
                    'w')  # Initialize the text exporter
                Writer_TouchEventTxt.write('TrialNum\tResult\tPanel\tyyyy/mm/dd\th:m\ts\tDelay(s)\tDelay type\n')  # Write item name
                print("Task #" + str(GetTaskID()) + " is started at " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(
                    GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

            if Phase2 == 0:  # Initiation of new trial
                TaskDur = Timer_GetSec(5)
                DoneCorrectResponse = 0
                SamplePanelID = int(random.random() * 2)  # Determine which position is correct at random
                if SamplePanelID == 1:
                    SamplePanelID = 2
                print('Trial: ' + str(CurrTrialNum))
                Trg = 0
                if CurrTrialNum <= 1:
                    TouchHistory[CurrTrialNum][0] = SamplePanelID
                if CurrTrialNum > 1:
                    if SamplePanelID == TouchHistory[CurrTrialNum - 1][0] and SamplePanelID == TouchHistory[CurrTrialNum - 2][0]:  # If Correct position is same as previous and pre-previous position
                        if SamplePanelID == 0:
                            SamplePanelID = 2  # Change correct position to the opposite side
                            Trg = 1
                        if SamplePanelID == 2 and Trg == 0:
                            SamplePanelID = 0  # Change correct position to the opposite side
                TouchHistory[CurrTrialNum][0] = SamplePanelID
                if SamplePanelID == 0:
                    CreateBlinkPanel(0)
                    ShowPanel(0)
                if SamplePanelID == 2:
                    CreateBlinkPanel(2)
                    ShowPanel(2)
                Writer_TouchEventTxt.write(
                    str(CurrTrialNum + 1) + '\tCueStart\t' + str(SamplePanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(
                        TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                Writer_TouchEventCsv.write(
                    str(CurrTrialNum + 1) + ',0,' + str(SamplePanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(
                        TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                Timer_Start(0)  # Start the latency timer
                Phase2 = 1

            if Phase2 == 1:  # Sample panel presentation phase
                TouchedPanelID = DetectRoiNosepoke()  # Check which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID == SamplePanelID:  # If mouse touches CORRECT panel
                    DoneCorrectResponse = 1

                    NowDrinking = 0
                    Writer_TouchEventTxt.write(
                        str(CurrTrialNum + 1) + '\tCueCorrectTouch\t' + str(SamplePanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(
                            TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                    Writer_TouchEventCsv.write(
                        str(CurrTrialNum + 1) + ',1,' + str(SamplePanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(
                            TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                    HidePanel(0)
                    HidePanel(2)
                    Timer_End(0)

                    DelayRand = int(random.random() * 2)
                    Trg = 0
                    if CurrTrialNum > 1:
                        if DelayRand == DelayHistory[CurrTrialNum - 1] and DelayRand == DelayHistory[CurrTrialNum - 2]:  # If Correct position is same as previous and pre-previous position
                            if DelayRand == 0:
                                DelayRand = 1  # Change correct position to the opposite side
                                Trg = 1
                            if DelayRand == 1 and Trg == 0:
                                DelayRand = 0  # Change correct position to the opposite side
                    DelayHistory[CurrTrialNum] = DelayRand  # Enter to the history
                    if DelayRand == 0:
                        DelayDur = DelayA  # If this trial is DelayA
                    if DelayRand == 1:
                        DelayDur = DelayB  # If this trial is DelayB
                    AllowedDelay = 10 + (DelayDur * DelayAllowFactor / 100)  # Caliculate threshold for data selection
                    # print(AllowedDelay)
                    Phase2 = 2  # Go to interval
                    Timer_Start(0)

                if Timer_GetSec(5) >= TimeLimit * 60:  # If time limit is exceeded
                    TaskDur = Timer_GetSec(5)
                    Timer_End(5)
                    Phase2 = 12

            if Phase2 == 2:  # Interval between sample touch and 1st center presentation
                # print(Timer_GetSec(0))
                if Timer_GetSec(0) >= 1:
                    CreateNormalPanel(1)
                    ShowPanel(1)  # Show 1st center panel
                    Phase2 = 3

            if Phase2 == 3:  # 1st center panel presentation phase
                TouchedPanelID = DetectRoiNosepoke()  # Check which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID == 1:  # If mouse touches 1st center panel
                    DoneCorrectResponse = 1

                    NowDrinking = 0
                    TouchHistory[CurrTrialNum][1] = (TimeNow.day * 60 * 60 * 24) + (TimeNow.hour * 60 * 60) + (TimeNow.minute * 60) + TimeNow.second
                    Writer_TouchEventTxt.write(
                        str(CurrTrialNum + 1) + '\t1stCenterCorrectTouch\t' + str(TouchedPanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(
                            TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                    Writer_TouchEventCsv.write(
                        str(CurrTrialNum + 1) + ',2,' + str(TouchedPanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(
                            TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                    HidePanel(1)
                    Timer_End(0)
                    Phase2 = 4  # Start reward phase
                    Timer_Start(0)
                if Timer_GetSec(5) >= TimeLimit * 60:  # If time limit is exceeded
                    TaskDur = Timer_GetSec(5)
                    Timer_End(5)
                    Phase2 = 12

            if Phase2 == 4:  # Interval between sample touch and 1st center presentation
                if Timer_GetSec(0) >= DelayDur:
                    CreateNormalPanel(1)
                    ShowPanel(1)  # Show 1st center panel
                    Phase2 = 5

            if Phase2 == 5:  # 2nd center panel presentation phase
                TouchedPanelID = DetectRoiNosepoke()  # Check which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID == 1:  # If mouse touches 1st center panel
                    DoneCorrectResponse = 1

                    NowDrinking = 0
                    Writer_TouchEventTxt.write(
                        str(CurrTrialNum + 1) + '\t2ndCenterCorrectTouch\t' + str(TouchedPanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(
                            TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file

                    Writer_TouchEventCsv.write(
                        str(CurrTrialNum + 1) + ',3,' + str(TouchedPanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(
                            TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                    HidePanel(1)
                    Timer_End(0)
                    Phase2 = 6  # Start reward phase
                    Timer_Start(0)
                if Timer_GetSec(5) >= TimeLimit * 60:  # If time limit is exceeded
                    TaskDur = Timer_GetSec(5)
                    Timer_End(5)
                    Phase2 = 12

            if Phase2 == 6:  # Interval between sample touch and 1st center presentation
                if Timer_GetSec(0) >= 1:
                    if SamplePanelID == 0:
                        if TaskType == 'DNMTP1':
                            CreateNormalPanel(2)
                            ShowPanel(2)  #
                        if TaskType == 'DMTP1':
                            CreateNormalPanel(0)
                            ShowPanel(0)  #
                        if TaskType == 'DNMTP2' or TaskType == 'DMTP2':
                            CreateNormalPanel(0)
                            CreateNormalPanel(2)
                            ShowPanel(0)  #
                            ShowPanel(2)  #
                    if SamplePanelID == 2:
                        if TaskType == 'DNMTP1':
                            CreateNormalPanel(0)
                            ShowPanel(0)  #
                        if TaskType == 'DMTP1':
                            CreateNormalPanel(2)
                            ShowPanel(2)  #
                        if TaskType == 'DNMTP2' or TaskType == 'DMTP2':
                            CreateNormalPanel(0)
                            CreateNormalPanel(2)
                            ShowPanel(0)  #
                            ShowPanel(2)  #
                    Phase2 = 7

            if Phase2 == 7:  # Choice phase
                TouchedPanelID = DetectRoiNosepoke()  # Check which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID != -1 and TouchedPanelID != 19:
                    TouchResult = 0
                    if TaskType == 'DMTP1' or TaskType == 'DMTP2':
                        if TouchedPanelID == SamplePanelID:  # If mouse touches same position with the sample phase
                            TouchResult = 1  # Correct
                        if TouchedPanelID != SamplePanelID and TouchedPanelID != 1:  # If mouse touches opposite position to the sample phase
                            TouchResult = -1  # Wrong
                    if TaskType == 'DNMTP1' or TaskType == 'DNMTP2':
                        if TouchedPanelID != SamplePanelID and TouchedPanelID != 1:  # If mouse touches opposite position to the sample phase
                            TouchResult = 1  # Correct

                        if TouchedPanelID == SamplePanelID:  # If mouse touches same position with the sample phase
                            TouchResult = -1  # Wrong
                    if TouchResult == 1:  # If mouse touches correct panel
                        DoneCorrectResponse = 1
                        NowDrinking = 0
                        TouchHistory[CurrTrialNum][2] = (TimeNow.day * 60 * 60 * 24) + (TimeNow.hour * 60 * 60) + (TimeNow.minute * 60) + TimeNow.second
                        TouchHistory[CurrTrialNum][3] = 1
                        TouchHistory[CurrTrialNum][4] = DelayRand
                        TrialNum[DelayRand] += 1
                        CorrectNum[DelayRand] += 1  # Increase the number of correct respon
                        TotalCorrectNum += 1
                        CorrectRate[DelayRand] = round(CorrectNum[DelayRand] * 100.0 / TrialNum[DelayRand], 2)
                        Writer_TouchEventTxt.write(
                            str(CurrTrialNum + 1) + '\tTestCorrectTouch\t' + str(TouchedPanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(
                                TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\t" + str(DelayDur) + "\t" + str(
                                DelayRand) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(
                            str(CurrTrialNum + 1) + ',4,' + str(TouchedPanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(
                                TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "," + str(DelayDur) + "," + str(
                                DelayRand) + "\n")  # Write the response on the csv file
                        HidePanel(0)
                        HidePanel(2)
                        Timer_End(0)
                        if WaterCueType == 'Normal':
                            DigitalOutOn(10)
                        if WaterCueType == 'Blink':
                            DigitalOutBlinkOn(10)
                        ServoPosInside(3)
                        Phase2 = 8  # Go to reward phase

                    if TouchResult == -1:  # If mouse touches wrong panel
                        DoneCorrectResponse = 0
                        NowDrinking = 0
                        TouchHistory[CurrTrialNum][2] = (TimeNow.day * 60 * 60 * 24) + (TimeNow.hour * 60 * 60) + (TimeNow.minute * 60) + TimeNow.second
                        TouchHistory[CurrTrialNum][3] = 0
                        TouchHistory[CurrTrialNum][4] = DelayRand
                        TrialNum[DelayRand] += 1
                        IncorrectNum[DelayRand] += 1  # Increase the number of correct response
                        CorrectRate[DelayRand] = round(CorrectNum[DelayRand] * 100.0 / TrialNum[DelayRand], 2)
                        Writer_TouchEventTxt.write(
                            str(CurrTrialNum + 1) + '\tTestIncorrectTouch\t' + str(TouchedPanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(
                                TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\t" + str(DelayDur) + "\t" + str(
                                DelayRand) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(
                            str(CurrTrialNum + 1) + ',5,' + str(TouchedPanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(
                                TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "," + str(DelayDur) + "," + str(
                                DelayRand) + "\n")  # Write the response on the csv file
                        HidePanel(0)
                        HidePanel(2)
                        Timer_End(0)
                        if PunishWithLight == 'ON':
                            RoofLightOn()  # Turn on roof light
                        ServoPosOutside(3)
                        Phase2 = 8  # Start reward phase
                        Timer_Start(0)

                if Timer_GetSec(5) >= TimeLimit * 60:  # If time limit is exceeded
                    TaskDur = Timer_GetSec(5)
                    Timer_End(5)
                    Phase2 = 12

            if Phase2 == 8:
                for i2 in range(2):
                    # Caliculate valid score
                    ValidTouchNum = 0
                    ValidCorrectNum = 0
                    ValidIncorrectNum = 0
                    for i in range(CurrTrialNum + 1):  # Loop for trials
                        if TouchHistory[i][2] == -1:  # If this trial is not completed
                            break
                        if TouchHistory[i][4] == i2:  # If this trial is completed
                            if TouchHistory[i][2] != -1:  # If this trial is completed
                                ActualDelay = TouchHistory[i][2] - TouchHistory[i][1]
                                if ActualDelay <= AllowedDelay:
                                    ValidTouchNum += 1
                                    if TouchHistory[i][3] == 1:
                                        ValidCorrectNum += 1
                                    if TouchHistory[i][3] == 0:
                                        ValidIncorrectNum += 1
                    if ValidTouchNum > 0:
                        ValidCorrectRate = round(ValidCorrectNum / ValidTouchNum * 100, 1)
                        ValidString[i2] = '  /  ValidCorrect:' + str(ValidCorrectNum) + '  ValidWrong:' + str(ValidIncorrectNum) + '  ValidTotalNum:' + str(ValidTouchNum) + '  ValidCorrect:' + str(
                            ValidCorrectRate) + '%'
                ResultStringA = 'Delay ' + str(DelayA) + 's : CorrectNum:' + str(CorrectNum[0]) + '  IncorrectNum:' + str(IncorrectNum[0]) + '  TrialNum:' + str(TrialNum[0]) + '  Correct:' + str(
                    CorrectRate[0]) + '%' + ValidString[0]
                ResultStringB = 'Delay ' + str(DelayB) + 's : CorrectNum:' + str(CorrectNum[1]) + '  IncorrectNum:' + str(IncorrectNum[1]) + '  TrialNum:' + str(TrialNum[1]) + '  Correct:' + str(
                    CorrectRate[1]) + '%' + ValidString[1]
                mOngoingResultVar.set(ResultStringA + '\n' + ResultStringB)
                if DoneCorrectResponse == 1:
                    Phase2 = 9
                if DoneCorrectResponse == 0:
                    Phase2 = 10

            if Phase2 == 9:  # Reward phase
                if DetectRoiNosepoke() == 19 and NowDrinking == 0:  # If the mouse initiates nose poke
                    NowDrinking = 1
                    Timer_Start(0)  # Start lick timer
                if NowDrinking == 1:
                    if DoneCorrectResponse == 1 and Timer_GetSec(0) >= LickDur:  # If lick time exceed the designated time
                        Timer_End(0)  # End lick timer
                        ServoPosMiddle(3)  # Move water nozzle to the intermediate position
                        DigitalOutOff(10)
                        NowDrinking = 0
                        Timer_Start(0)  # Start ITI timer
                        Phase2 = 11  # Go to ITI

            if Phase2 == 10:  # Punishment phase
                if Timer_GetSec(0) >= PunishDur:  # If punishment time is passed
                    RoofLightOff()
                    ServoPosMiddle(3)  # Move water nozzle to the intermediate position
                    Timer_End(0)  # End punishment timer1
                    Timer_Start(0)  # Start ITI timer
                    Phase2 = 11  # Go to ITI

            if Phase2 == 11:  # ITI
                if Timer_GetSec(0) >= Iti:  # If ITI is passed
                    if TotalCorrectNum >= MaxCorrectNum or CurrTrialNum >= MaxTrialNum - 1:  # If mouse achieved criteria of finishing the task
                        Timer_End(5)
                        ServoPosMiddle(3)
                        DigitalOutOff(10)
                        Timer_Start(0)  # Timer for interval between task and arbitary water supply is started
                        Phase2 = 12  # Go to the AWS
                    else:
                        CurrTrialNum += 1
                        Phase2 = 0  # Go to the next trial

            if Phase2 == 12:  # End session
                HidePanel(0)
                HidePanel(1)
                HidePanel(2)
                HidePanel(3)
                HidePanel(4)
                if TotalCorrectNum < MaxCorrectNum and AwsOn == 'ON':  # If mouse didn't achieved the max correct response
                    Timer_Start(0)
                    Phase2 = 13
                if TotalCorrectNum == MaxCorrectNum or AwsOn == 'OFF':  # If mouse achieved the max correct response
                    Phase2 = -1

            if Phase2 == 13:  # Wait until arbitary water suuply is started
                if Timer_GetSec(0) >= 20:  # If the interval is past 20
                    Timer_End(0)
                    ArbitaryWaterSupplyDur = (MaxCorrectNum - TotalCorrectNum) * LickDur * 1000  # Caliculate duration of complement water supply
                    if WaterCueType == 'Normal':
                        StartArbitaryWaterSupply(3,10,0,ArbitaryWaterSupplyDur) # Start complement water supply
                    if WaterCueType == 'Blink':
                        StartArbitaryWaterSupply(3,10,1,ArbitaryWaterSupplyDur) # Start complement water supply
                    print("AWSstart")
                    Phase2 = 14
            if Phase2 == 14:
                if GetArbitaryWaterSupplyStat() == 1:  # If complement water supply is finished
                    Phase2 = -1

            if Phase2 == -1 or GetEndTaskNowButtonStat() == 1:  # Task finish phase
                LightCycleControlOn()
                ServoPosMiddle(3)
                DeleteAllPanel()
                InfraredLightOff()
                if GetRecordingStat() == 1:
                    SetEndRecordingTimer(60)

                if CurrTrialNum > 0:
                    Writer_TouchEventTxt.write(ResultStringA + '\n' + ResultStringB + '\n')  # Summary of results
                Writer_TouchEventTxt.write('SessionStartTime: ' + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()) + "\n")
                Writer_TouchEventTxt.write('SessionEndTime: ' + str(TimeNow.month) + '/' + str(TimeNow.day) + ' ' + str(TimeNow.hour) + ':' + str(TimeNow.minute) + ':' + str(TimeNow.second + (TimeNow.microsecond // 1000) / 1000) + "\n")
                Writer_TouchEventTxt.write('TaskDuration(sec): ' + str(GetTaskID()) + "\n")
                Writer_TouchEventTxt.write('DelayA: ' + str(DelayA) + " sec\n")
                Writer_TouchEventTxt.write('DelayB: ' + str(DelayB) + " sec\n")
                Writer_TouchEventTxt.write('MaxCorrectNum: ' + str(MaxCorrectNum) + "\n")
                Writer_TouchEventTxt.write('MaxTrialNum: ' + str(MaxTrialNum) + "\n")
                Writer_TouchEventTxt.write('TimeLimit: ' + str(TimeLimit) + " min\n")
                Writer_TouchEventTxt.write('PunishDur: ' + str(PunishDur) + " sec\n")
                Writer_TouchEventTxt.write('LickDur: ' + str(LickDur) + " sec\n")
                Writer_TouchEventTxt.write('Iti: ' + str(Iti) + " sec\n")
                Writer_TouchEventTxt.write('ValidDelay%: ' + str(DelayAllowFactor) + " %\n")
                Writer_TouchEventTxt.write('RateTh: ' + str(RateTh) + " %\n")
                Writer_TouchEventTxt.write('DayTh: ' + str(DayTh) + " day\n")
                Writer_TouchEventTxt.write('Seed: ' + str(Seed) + "\n")
                Writer_TouchEventTxt.write('NextTask: ' + str(NextTask) + "\n")
                Writer_TouchEventTxt.write('TaskType: ' + str(TaskType) + "\n")
                Writer_TouchEventTxt.write('WaterCueType: ' + str(WaterCueType) + "\n")
                Writer_TouchEventTxt.write('PunishLight: ' + str(PunishWithLight) + "\n")
                Writer_TouchEventTxt.write('RecordFPS: ' + str(GetRecordFps()) + "\n")
                Writer_TouchEventTxt.write('AWS: ' + AwsOn + "\n")
                Writer_TouchEventTxt.write('AWS_Latency: ' + str(AWS_Latency) + "\n")
                Writer_TouchEventTxt.write(GetRoiSensitivity() + "\n")
                Writer_TouchEventTxt.write(GetServoAngle() + "\n")

                Writer_TouchEventTxt.close()
                Writer_TouchEventCsv.close()
                EndLickRecording()

                SendMail(DeviceNameVar.get() + ' finished task ' + str(GetTaskID()) + '.' + ResultStringA + ';  ' + ResultStringB + ';  Dur:' + str(round(Timer_GetSec(5) / 60, 1)) + ' min',
                    'Task is finished.')

                if IsHousingAnalysis == 1:  #
                    SeedVar.set(Seed + 1)
                    # Update condition of experiment
                    if LearningPhase == 0:  # If it is acquisition phase
                        TotalCorrectRate = 0.0
                        if TrialNum[0]!=0 or TrialNum[1]!=0:
                            TotalCorrectRate = (CorrectNum[0] + CorrectNum[1]) * 100 / (TrialNum[0] + TrialNum[1])

                        #if CurrTrialNum != 0:
                        if TotalCorrectRate >= RateTh:  # If correct rate exceeded the criteria
                            ThClearDay += 1  # Increase the criteria counter
                            print("Current cleared stream days:" + str(ThClearDay))
                            if ThClearDay >= DayTh:  # If acquisition is completed
                                LearningPhase = 1  # Go to the delayed phase
                                print("Delayed phase is started")
                        if TotalCorrectRate < RateTh:  # If correct rate belowed the criteria
                            ThClearDay = 0  # Reset the criteria counter
                    if LearningPhase == 1:  # If it is delayed phase
                        SessionDelayID += 1  # Change delay
                        if SessionDelayID == 1:
                            print("Next delay is " + Delay0Var.get() + " sec / " + Delay1Var.get() + " sec")
                        if SessionDelayID == 2:
                            print("Next delay is " + Delay1Var.get() + " sec / " + Delay2Var.get() + " sec")
                        if SessionDelayID == 3:
                            print("Next delay is " + Delay2Var.get() + " sec / " + Delay3Var.get() + " sec")
                        if SessionDelayID == 4:
                            print("Next delay is " + Delay3Var.get() + " sec / " + Delay4Var.get() + " sec")
                        if SessionDelayID == 5:
                            print("Next delay is " + Delay4Var.get() + " sec / " + Delay5Var.get() + " sec")
                        if SessionDelayID == 6:
                            print("Next delay is " + Delay5Var.get() + " sec / " + Delay6Var.get() + " sec")
                        if SessionDelayID == 7:
                            print("Next delay is " + Delay6Var.get() + " sec / " + Delay7Var.get() + " sec")
                        if SessionDelayID == 8:
                            print("Next delay is " + Delay7Var.get() + " sec / " + Delay8Var.get() + " sec")
                        if SessionDelayID == 9:
                            print("Next delay is " + Delay8Var.get() + " sec / " + Delay9Var.get() + " sec")
                        if Phase2 == -1:
                            if SessionDelayID > NumOfDelayID - 1:  # If the last delayed session is finished (This task is completed)
                                print(NumOfDelayID)
                                SwitchTask(NextTask)  # Onset task switch trigger
                                print("Task is switched to task#" + str(NextTask) + "  " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(
                                    GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

                if IsHousingAnalysis == 0:
                    RoofLightOn()

                Phase = 1  # Go back to the task-waiting phase
                Phase2 = 0
                Phase2_Init = 0
            SetDispVariable(0, 'Phase2', str(Phase2))  # Display "Phase2" value on the main window
    return

def Task8():   # Delayed alteration task (DAT)
    global Phase
    Phase0_Init=0
    Phase1_Init=0
    Phase2_Init=0
    while EndFlag==0:
        OperantHouseUpdate()
        if GetBackButtonStat()==1:    # If "Back" button is clicked
            break   # Back to the task select phase
        if Phase == 0:  # Parameter inputs
            if Phase0_Init == 0:
                # Make GUI for the setting of the parameters for this task
                RemoveMainRightWidget() # Remove task buttons
                PutStartBackButton()    # Put start/back buttons

                ColumnWidth = 11
                Row = 0    # Begin a new line
                Column = 0

                mMaxCorrectNum = ttk.Label(MainWindowRightFrame, text='MaxCorrect', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                MaxCorrectNumVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iMaxCorrectNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxCorrectNumVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column+=1  # Shift column
                mMaxTrialNum = ttk.Label(MainWindowRightFrame, text='MaxTrial', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                MaxTrialNumVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iMaxTrialNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxTrialNumVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mTimeLimit = ttk.Label(MainWindowRightFrame, text='Limit(min)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                TimeLimitVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iTimeLimit = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mPunishDur = ttk.Label(MainWindowRightFrame, text='PunishDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                PunishDurVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iPunishDur = ttk.Entry(MainWindowRightFrame, textvariable=PunishDurVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mLickDur = ttk.Label(MainWindowRightFrame, text='LickDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                LickDurVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iLickDur = ttk.Entry(MainWindowRightFrame, textvariable=LickDurVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mDelayAllowFactor = ttk.Label(MainWindowRightFrame, text='ValidDelay%', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                DelayAllowFactorVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelayAllowFactor = ttk.Entry(MainWindowRightFrame, textvariable=DelayAllowFactorVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mRateTh = ttk.Label(MainWindowRightFrame, text='RateTh(%)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                RateThVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iRateTh = ttk.Entry(MainWindowRightFrame, textvariable=RateThVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mDayTh = ttk.Label(MainWindowRightFrame, text='DayTh(d)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                DayThVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDayTh = ttk.Entry(MainWindowRightFrame, textvariable=DayThVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mNextTask = ttk.Label(MainWindowRightFrame, text='NextTask', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                NextTaskVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iNextTask = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field

                Row += 2  # Begin a new line
                Column = 0
                mCorrectPos = ttk.Label(MainWindowRightFrame, text='CorrectPos', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                CorrectPosVar = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                tCorrectPos = OptionMenu(MainWindowRightFrame, CorrectPosVar, "0", "1").grid(row=Row+1, column=Column)  # Put dropdown list
                Column += 1  # Shift column
                mPanelType = ttk.Label(MainWindowRightFrame, text='PanelType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                PanelTypeVar = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                tPanelType = OptionMenu(MainWindowRightFrame, PanelTypeVar, "Normal", "Blink", "Textured").grid(row=Row+1, column=Column)  # Put dropdown list
                Column += 1  # Shift column
                mWaterCueType = ttk.Label(MainWindowRightFrame, text='WaterCue', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                WaterCueTypeVar = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                tWaterCueType = OptionMenu(MainWindowRightFrame, WaterCueTypeVar, "Normal", "Blink").grid(row=Row+1, column=Column)  # Put dropdown list
                Column += 1  # Shift column
                mPunishWithLight = ttk.Label(MainWindowRightFrame, text='PunishLight', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                PunishWithLightVar = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                tPunishWithLight = OptionMenu(MainWindowRightFrame, PunishWithLightVar, "ON", "OFF").grid(row=Row+1, column=Column)  # Put dropdown list
                Column += 1  # Shift column
                mAwsOn = ttk.Label(MainWindowRightFrame, text='AWS', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                AwsOnVar = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                tAwsOn = OptionMenu(MainWindowRightFrame, AwsOnVar, "ON", "OFF").grid(row=Row+1, column=Column)  # Put dropdown list

                Row += 2  # Begin a new line
                Column =0

                mDelay0 = ttk.Label(MainWindowRightFrame, text='Delay0(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                Delay0Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay0 = ttk.Entry(MainWindowRightFrame, textvariable=Delay0Var, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mDelay1 = ttk.Label(MainWindowRightFrame, text='Delay1(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                Delay1Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay1 = ttk.Entry(MainWindowRightFrame, textvariable=Delay1Var, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mDelay2 = ttk.Label(MainWindowRightFrame, text='Delay2(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                Delay2Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay2 = ttk.Entry(MainWindowRightFrame, textvariable=Delay2Var, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mDelay3 = ttk.Label(MainWindowRightFrame, text='Delay3(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                Delay3Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay3 = ttk.Entry(MainWindowRightFrame, textvariable=Delay3Var, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mDelay4 = ttk.Label(MainWindowRightFrame, text='Delay4(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                Delay4Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay4 = ttk.Entry(MainWindowRightFrame, textvariable=Delay4Var, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mDelay5 = ttk.Label(MainWindowRightFrame, text='Delay5(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                Delay5Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay5 = ttk.Entry(MainWindowRightFrame, textvariable=Delay5Var, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mDelay6 = ttk.Label(MainWindowRightFrame, text='Delay6(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                Delay6Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay6 = ttk.Entry(MainWindowRightFrame, textvariable=Delay6Var, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mDelay7 = ttk.Label(MainWindowRightFrame, text='Delay7(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                Delay7Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay7 = ttk.Entry(MainWindowRightFrame, textvariable=Delay7Var, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mDelay8 = ttk.Label(MainWindowRightFrame, text='Delay8(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                Delay8Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay8 = ttk.Entry(MainWindowRightFrame, textvariable=Delay8Var, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mDelay9 = ttk.Label(MainWindowRightFrame, text='Delay9(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                Delay9Var = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay9 = ttk.Entry(MainWindowRightFrame, textvariable=Delay9Var, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field

                Str = "ParametersForTask" + str(GetTaskID())
                if os.path.exists(Str + '/MaxCorrectNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxCorrectNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxCorrectNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxCorrectNumVar.set(80)  # Default value

                if os.path.exists(Str + '/MaxTrialNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxTrialNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxTrialNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxTrialNumVar.set(999)  # Default value

                if os.path.exists(Str + '/TimeLimit.dat') == True:  # If save file exists
                    with open(Str + '/TimeLimit.dat', 'rb') as PickleInst[GetTaskID()]:
                        TimeLimitVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    TimeLimitVar.set(600)  # Default value

                if os.path.exists(Str + '/PunishDur.dat') == True:  # If save file exists
                    with open(Str + '/PunishDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishDurVar.set(10)  # Default value

                if os.path.exists(Str + '/LickDur.dat') == True:  # If save file exists
                    with open(Str + '/LickDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        LickDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    LickDurVar.set(2)  # Default value

                if os.path.exists(Str + '/DelayAllowFactor.dat') == True:  # If save file exists
                    with open(Str + '/DelayAllowFactor.dat', 'rb') as PickleInst[GetTaskID()]:
                        DelayAllowFactorVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    DelayAllowFactorVar.set(130)  # Default value

                if os.path.exists(Str + '/RateTh.dat') == True:  # If save file exists
                    with open(Str + '/RateTh.dat', 'rb') as PickleInst[GetTaskID()]:
                        RateThVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    RateThVar.set(80)  # Default value

                if os.path.exists(Str + '/DayTh.dat') == True:  # If save file exists
                    with open(Str + '/DayTh.dat', 'rb') as PickleInst[GetTaskID()]:
                        DayThVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    DayThVar.set(2)  # Default value

                if os.path.exists(Str + '/NextTask.dat') == True:  # If save file exists
                    with open(Str + '/NextTask.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskVar.set(8)  # Default value

                if os.path.exists(Str + '/CorrectPos.dat') == True:  # If save file exists
                    with open(Str + '/CorrectPos.dat', 'rb') as PickleInst[GetTaskID()]:
                        CorrectPosVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    CorrectPosVar.set('0')  # Default value

                if os.path.exists(Str + '/PanelType.dat') == True:  # If save file exists
                    with open(Str + '/PanelType.dat', 'rb') as PickleInst[GetTaskID()]:
                        PanelTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PanelTypeVar.set('Normal')  # Default value

                if os.path.exists(Str + '/WaterCueType.dat') == True:  # If save file exists
                    with open(Str + '/WaterCueType.dat', 'rb') as PickleInst[GetTaskID()]:
                        WaterCueTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    WaterCueTypeVar.set('Blink')  # Default value

                if os.path.exists(Str + '/PunishWithLight.dat') == True:  # If save file exists
                    with open(Str + '/PunishWithLight.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishWithLightVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishWithLightVar.set('ON')  # Default value

                if os.path.exists(Str + '/Delay0.dat') == True:  # If save file exists
                    with open(Str + '/Delay0.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay0Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay0Var.set('0')  # Default value
                if os.path.exists(Str + '/AwsOn.dat') == True:  # If save file exists
                    with open(Str + '/AwsOn.dat', 'rb') as PickleInst[GetTaskID()]:
                        AwsOnVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    AwsOnVar.set('OFF')  # Default value
                if os.path.exists(Str + '/Delay1.dat') == True:  # If save file exists
                    with open(Str + '/Delay1.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay1Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay1Var.set('2')  # Default value
                if os.path.exists(Str + '/Delay2.dat') == True:  # If save file exists
                    with open(Str + '/Delay2.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay2Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay2Var.set('5')  # Default value
                if os.path.exists(Str + '/Delay3.dat') == True:  # If save file exists
                    with open(Str + '/Delay3.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay3Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay3Var.set('9')  # Default value
                if os.path.exists(Str + '/Delay4.dat') == True:  # If save file exists
                    with open(Str + '/Delay4.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay4Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay4Var.set('14')  # Default value
                if os.path.exists(Str + '/Delay5.dat') == True:  # If save file exists
                    with open(Str + '/Delay5.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay5Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay5Var.set('20')  # Default value
                if os.path.exists(Str + '/Delay6.dat') == True:  # If save file exists
                    with open(Str + '/Delay6.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay6Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay6Var.set('27')  # Default value
                if os.path.exists(Str + '/Delay7.dat') == True:  # If save file exists
                    with open(Str + '/Delay7.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay7Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay7Var.set('49')  # Default value
                if os.path.exists(Str + '/Delay8.dat') == True:  # If save file exists
                    with open(Str + '/Delay8.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay8Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay8Var.set('87')  # Default value
                if os.path.exists(Str + '/Delay9.dat') == True:  # If save file exists
                    with open(Str + '/Delay9.dat', 'rb') as PickleInst[GetTaskID()]:
                        Delay9Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Delay9Var.set('157')  # Default value

                RemoveAllRoiGui()
                PutRoiGui(0, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(1, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(19, 0, 0, 1)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)

                RemoveAllDigitalOutGui()
                PutDigitalOutGui(10)
                PutDigitalOutGui(12)
                PutDigitalOutGui(13)

                RemoveAllServoGui()
                PutServoGui(3)
                Phase0_Init = 1

        if GetSaveTrgStat() == 1:    # If save trigger is on
            # Parameters of each task are saved into different folder
            Str="ParametersForTask"+str(GetTaskID())   # Path to the folder for saving of parameters
            if os.path.exists(Str) == False:    # If folder for saving parameters is not exist
                os.mkdir(Str)   # Make folder for saving
            with open(Str+'/MaxCorrectNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxCorrectNumVar.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/MaxTrialNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxTrialNumVar.get(),PickleInst[GetTaskID()])     # Save
            with open(Str + '/TimeLimit.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TimeLimitVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str+'/PunishDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishDurVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str + '/LickDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(LickDurVar.get(), PickleInst[GetTaskID()])  # Save

            with open(Str + '/DelayAllowFactor.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(DelayAllowFactorVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/RateTh.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(RateThVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/DayTh.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(DayThVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/NextTask.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str+'/CorrectPos.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(CorrectPosVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/PanelType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PanelTypeVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/WaterCueType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(WaterCueTypeVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/PunishWithLight.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishWithLightVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str + '/AwsOn.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(AwsOnVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str+'/Delay0.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay0Var.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/Delay1.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay1Var.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/Delay2.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay2Var.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/Delay3.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay3Var.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/Delay4.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay4Var.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/Delay5.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay5Var.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/Delay6.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay6Var.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/Delay7.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay7Var.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/Delay8.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay8Var.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/Delay9.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Delay9Var.get(),PickleInst[GetTaskID()])     # Save

        if Phase == 1:  # Wait for starting of task
            if Phase1_Init == 0:
                PutPreTaskButton()
                mStatusVar = StringVar(MainWindowRoot)
                mStatus = ttk.Label(MainWindowRightFrame, textvariable=mStatusVar)
                mStatus.place(x=10, y=0)
                mOngoingResultVar = StringVar(MainWindowRoot)
                DatPhase = 0       # Phase of task, 0:Acquisition, 1:DelayedTask
                ThClearDay=0        # Number of stream days where criteria threshold is achieved
                CurrDelayID = 0    # Assign current delay ID (0-9)
                NumOfDelayID=1
                for i in range(9):
                    if i==1:
                        if Delay1Var.get()!='': # If delay is designated
                            NumOfDelayID+=1
                        if Delay1Var.get() == '':   # If delay is not designated
                            break
                    if i==2:
                        if Delay2Var.get()!='': # If delay is designated
                            NumOfDelayID+=1
                        if Delay2Var.get() == '':   # If delay is not designated
                            break
                    if i==3:
                        if Delay3Var.get()!='': # If delay is designated
                            NumOfDelayID+=1
                        if Delay3Var.get() == '':   # If delay is not designated
                            break
                    if i==4:
                        if Delay4Var.get()!='': # If delay is designated
                            NumOfDelayID+=1
                        if Delay4Var.get() == '':   # If delay is not designated
                            break
                    if i==5:
                        if Delay5Var.get()!='': # If delay is designated
                            NumOfDelayID+=1
                        if Delay5Var.get() == '':   # If delay is not designated
                            break
                    if i==6:
                        if Delay6Var.get()!='': # If delay is designated
                            NumOfDelayID+=1
                        if Delay6Var.get() == '':   # If delay is not designated
                            break
                    if i==7:
                        if Delay7Var.get()!='': # If delay is designated
                            NumOfDelayID+=1
                        if Delay7Var.get() == '':   # If delay is not designated
                            break
                    if i==8:
                        if Delay8Var.get()!='': # If delay is designated
                            NumOfDelayID+=1
                        if Delay8Var.get() == '':   # If delay is not designated
                            break
                    if i==9:
                        if Delay9Var.get()!='': # If delay is designated
                            NumOfDelayID+=1
                        if Delay9Var.get() == '':   # If delay is not designated
                            break
                print('Num of delays: ' + str(NumOfDelayID))

                Phase1_Init = 1
            mStatusVar.set('Delayed alteration task (' + str(GetTaskID()) + ')    Waiting...')
            if IsStartTime() == 1:  # If task start time is arrived
                StartNow()
        if Phase == 2:  # During task
            if Phase2_Init == 0: # Initialization of the task
                PutEndTaskNowButton()

                mStatusVar.set('Delayed alteration task (' + str(GetTaskID()) + ')    Start time ' + str(TaskStartedMonth) + '/' + str(TaskStartedDay) + ' ' + str(TaskStartedHour) + ':' + str(TaskStartedMinute) + '    Running')
                mOngoingResult = ttk.Label(MainWindowRightFrame, textvariable=mOngoingResultVar)
                mOngoingResult.place(x=10, y=18)

                # Convert StringVars of parameters into integer or normal string to use in the following
                MaxCorrectNum=int(MaxCorrectNumVar.get())
                MaxTrialNum = int(MaxTrialNumVar.get())
                TimeLimit = float(TimeLimitVar.get())
                PunishDur = float(PunishDurVar.get())
                LickDur = float(LickDurVar.get())
                AwsOn=AwsOnVar.get()
                DelayAllowFactor = float(DelayAllowFactorVar.get())
                RateTh = float(RateThVar.get())
                DayTh = int(DayThVar.get())
                NextTask = int(NextTaskVar.get())
                CorrectPos =int(CorrectPosVar.get())
                PanelType = PanelTypeVar.get()
                WaterCueType = WaterCueTypeVar.get()
                PunishWithLight = PunishWithLightVar.get()
                if CurrDelayID==0:
                    Iti=int(Delay0Var.get())
                if CurrDelayID==1:
                    Iti=int(Delay1Var.get())
                if CurrDelayID==2:
                    Iti=int(Delay2Var.get())
                if CurrDelayID==3:
                    Iti=int(Delay3Var.get())
                if CurrDelayID==4:
                    Iti=int(Delay4Var.get())
                if CurrDelayID == 5:
                    Iti = int(Delay5Var.get())
                if CurrDelayID == 6:
                    Iti = int(Delay6Var.get())
                if CurrDelayID == 7:
                    Iti = int(Delay7Var.get())
                if CurrDelayID == 8:
                    Iti = int(Delay8Var.get())
                if CurrDelayID == 9:
                    Iti = int(Delay9Var.get())
                AllowedDelay = 10 + (Iti * DelayAllowFactor / 100)
                StartLickRecording()
                RoofLightOff()
                InfraredLightOn()
                if WaterCueType == 'Normal':
                    DigitalOutOn(10)
                if WaterCueType == 'Blink':
                    DigitalOutBlinkOn(10)
                ServoPosInside(3)
                if PanelType=='Normal':
                    CreateNormalPanel(0)
                    CreateNormalPanel(1)
                if PanelType=='Blink':
                    CreateBlinkPanel(0)
                    CreateBlinkPanel(1)
                if PanelType=='Textured':
                    CreateTexturedPanel(0,0)
                    CreateTexturedPanel(1,0)

                # Declar local variables for this task
                TotalTouchNum = 0
                CorrectNum = 0
                IncorrectNum = 0
                CorrectRate = 0
                ValidCorrectNum=0   # Correct touch num which have done within the designated delay
                ValidIncorrectNum = 0
                ValidTouchNum=0
                ValidCorrectRate=0  # Correct rate which have done within the designated delay
                TouchInfo=[[0 for i in range(2)] for j in range(MaxTrialNum)]   # Keep right or wrong and time of touching (For valid trial selection)
                ValidString=""
                TaskDur = 0

                LightCycleControlOff()
                DoneCorrectResponse = 1
                DuringDelay = 0
                NowDrinking = 0
                AWS_Latency = 20
                StartRecording()    # Start camera capturing and sending of TTL

                TrialNum=0

                Timer_Start(5)  # Task time limit timer start
                Phase2 = 2
                Phase2_Init = 1

                Writer_TouchEventTxt = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(Task) +  " Touch.txt",'w')  # Initialize the text exporter
                Writer_TouchEventCsv = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(Task) +  " Touch.csv",'w')  # Initialize the text exporter
                Writer_TouchEventTxt.write('TrialNum\tResult\t\t\tyyyy/mm/dd\th:m\ts\n')  # Write item name
                print("Task #" + str(GetTaskID()) + " is started at " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(
                    GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

            if Phase2 == 0:   # Initiation of new trial
                TaskDur = Timer_GetSec(5)
                DoneCorrectResponse=0
                DuringDelay = 0
                TrialNum += 1

                ShowPanel(0)
                ShowPanel(1)

                Timer_Start(0)  # Start the latency timer
                Phase2 += 1
            if Phase2 == 1:   # Panel presentation
                TouchedPanelID = DetectRoiNosepoke() # Examine which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID != -1 and TouchedPanelID != 19:
                    #ShowTouchSymbol(30)
                    if TouchedPanelID == int(CorrectPos): # If mouse touchs CORRECT panel
                        DoneCorrectResponse = 1

                        NowDrinking = 0
                        CorrectNum += 1  # Increase the number of correct respon
                        TouchInfo[TotalTouchNum][0]=1
                        TouchInfo[TotalTouchNum][1] = (TimeNow.hour*60*60)+(TimeNow.minute*60)+TimeNow.second
                        TotalTouchNum+=1
                        CorrectRate=round(CorrectNum*100.0/TotalTouchNum, 2)
                        mOngoingResultVar.set('CorrectNum:'+str(CorrectNum)+'  IncorrectNum:'+str(IncorrectNum)+'  TotalNum:'+str(TotalTouchNum)+'  Correct:'+str(CorrectRate)+'%'+ValidString)
                        Writer_TouchEventTxt.write(str(TrialNum) + '\tPanelTouched(Correct)\t' +str(TouchedPanelID)+'\t'+ str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',1,' +str(TouchedPanelID)+','+ str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the csv file
                        HidePanel(0)
                        HidePanel(1)
                        Timer_End(0)
                        if WaterCueType == 'Normal':
                            DigitalOutOn(10)
                        if WaterCueType == 'Blink':
                            DigitalOutBlinkOn(10)
                        Phase2 = 2  # Start reward phase
                        DuringDelay=1
                        Timer_Start(0)
                    if TouchedPanelID != int(CorrectPos): # If mouse touchs WRONG panel
                        ServoPosOutside(3)
                        if PunishWithLight == 'ON':
                            RoofLightOn()  # Turn on roof light
                        IncorrectNum += 1
                        TouchInfo[TotalTouchNum][0] = -1
                        TouchInfo[TotalTouchNum][1] = (TimeNow.hour * 60 * 60) + (TimeNow.minute * 60) + TimeNow.second
                        TotalTouchNum += 1
                        CorrectRate = round(CorrectNum * 100.0 / TotalTouchNum, 2)
                        mOngoingResultVar.set('CorrectNum:' + str(CorrectNum) + '  IncorrectNum:' + str(IncorrectNum) + '  TotalNum:' + str(TotalTouchNum) + '  Correct:' + str(CorrectRate)+'%'+ValidString)
                        Writer_TouchEventTxt.write(str(TrialNum) + '\tPanelTouched(Wrong)\t' +str(TouchedPanelID)+'\t'+ str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',0,' +str(TouchedPanelID)+','+ str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the csv file
                        HidePanel(0)
                        HidePanel(1)
                        Timer_End(0)  # End timer1
                        Timer_Start(0)  # Start punish timer
                        Phase2 = 5  # Start punishment phase
                if Timer_GetSec(5) >= TimeLimit * 60:   # If time limit is exceeded
                    TaskDur = Timer_GetSec(5)
                    Timer_End(5)
                    Phase2 = 6
            if Phase2 == 2:  # Reward phase
                if DuringDelay==1:
                    if Timer_GetSec(0) >= Iti:
                        ServoPosInside(3)  # Move water nozzle to the inside position
                        DuringDelay=0
                if DuringDelay == 0:
                    if DetectRoiNosepoke() == 19 and NowDrinking == 0:    # If the mouse initiates nose poke
                        NowDrinking = 1
                        Timer_Start(0)  # Start lick timer
                    if NowDrinking == 1:
                        if DoneCorrectResponse == 1 and Timer_GetSec(0) >= LickDur:   # If lick time exceed the designated time
                            Timer_End(0) # End lick timer
                            ServoPosMiddle(3)    # Move water nozzle to the intermediate position
                            DigitalOutOff(10)
                            NowDrinking = 0
                            Trg = 0
                            if CorrectPos==0:
                                CorrectPos =1
                                Trg=1
                            if CorrectPos==1 and Trg==0:
                                CorrectPos =0
                            Phase2 = 3

            if Phase2 == 3:   # ITI
                # Caliculate valid score
                ValidTouchNum=0
                ValidCorrectNum=0
                ValidIncorrectNum=0
                for i in range(TotalTouchNum):  #
                    if TouchInfo[i][0] == 0:
                        break
                    if i > 0:
                        if TouchInfo[i - 1][0] == 1:  # If previous touch is correct
                            ActualDelay = TouchInfo[i][1] - TouchInfo[i - 1][1]
                            if ActualDelay <= AllowedDelay:
                                ValidTouchNum += 1
                                if TouchInfo[i][0] == 1:
                                    ValidCorrectNum += 1
                                if TouchInfo[i][0] == -1:
                                    ValidIncorrectNum += 1
                if ValidTouchNum > 0:
                    ValidCorrectRate = round(ValidCorrectNum/ValidTouchNum*100,1)
                    ValidString='  /  ValidCorrect:'+str(ValidCorrectNum)+'  ValidWrong:'+str(ValidIncorrectNum)+'  ValidTotalNum:'+str(ValidTouchNum)+'  ValidCorrect:'+str(ValidCorrectRate)+'%'
                    mOngoingResultVar.set('CorrectNum:' + str(CorrectNum) + '  IncorrectNum:' + str(IncorrectNum) + '  TotalNum:' + str(TotalTouchNum) + '  Correct:' + str(round(CorrectNum * 100.0 / TotalTouchNum, 2)) + '%' + ValidString)

                if CorrectNum >= MaxCorrectNum or TotalTouchNum >= MaxTrialNum: # If mouse achieved criteria of finishing the task
                    Timer_End(5)
                    ServoPosMiddle(3)
                    DigitalOutOff(10)
                    Timer_Start(0)  # Timer for interval between task and arbitary water supply is started
                    Phase2 = 6  # Go to the AWS
                else:
                    Phase2 = 0  # Go to the next trial

            if Phase2 == 5:   # Punishment phase
                if Timer_GetSec(0) >= PunishDur:    # If punishment time is passed
                    RoofLightOff()
                    ServoPosMiddle(3)    # Move water nozzle to the intermediate position
                    Timer_End(0)  # End punishment timer1
                    Timer_Start(0)  # Start ITI timer
                    Phase2 = 3
            if Phase2==6:
                HidePanel(0)
                HidePanel(1)
                if CorrectNum < MaxCorrectNum and AwsOn == 'ON':  # If mouse didn't achieved the max correct response
                    Timer_Start(0)
                    Phase2 = 7
                if CorrectNum == MaxCorrectNum or AwsOn == 'OFF':  # If mouse achieved the max correct response
                    Phase2 = -1
            if Phase2==7:   # Wait until arbitary water suuply is started
                if Timer_GetSec(0) >= 20:   # If the interval is past 60
                    Timer_End(0)
                    ArbitaryWaterSupplyDur=(MaxCorrectNum - CorrectNum) * LickDur * 1000    # Caliculate duration of complement water supply
                    if WaterCueType == 'Normal':
                        StartArbitaryWaterSupply(3,10,0,ArbitaryWaterSupplyDur) # Start complement water supply
                    if WaterCueType == 'Blink':
                        StartArbitaryWaterSupply(3,10,1,ArbitaryWaterSupplyDur) # Start complement water supply
                    print("AWSstart")
                    Phase2=8
            if Phase2==8:
                if GetArbitaryWaterSupplyStat()==1: # If complement water supply is finished
                    Phase2 = -1

            if Phase2 == -1 or GetEndTaskNowButtonStat() == 1:  # Task finish phase
                LightCycleControlOn()
                ServoPosMiddle(3)
                DeleteAllPanel()
                InfraredLightOff()
                if GetRecordingStat() == 1:
                    SetEndRecordingTimer(60)
                if TotalTouchNum > 0:
                    CorrectRate = round(CorrectNum * 100.0 / TotalTouchNum,1)
                    Writer_TouchEventTxt.write('Correct num:'+str(CorrectNum)+'  Incorrect num:'+str(IncorrectNum)+'  TotalNum:'+str(TotalTouchNum)+'  Correct rate'+str(CorrectRate)+'%'+ValidString+"\n") #結果テキストの一番最後に成績のまとめを記入
                Writer_TouchEventTxt.write('SessionStartTime: ' + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(
                    GetTaskStartedSecond()) + "\n")
                Writer_TouchEventTxt.write('SessionEndTime: ' + str(TimeNow.month) + '/' + str(TimeNow.day) + ' ' + str(TimeNow.hour) + ':' + str(TimeNow.minute) + ':' + str(TimeNow.second + (TimeNow.microsecond // 1000) / 1000) + "\n")
                Writer_TouchEventTxt.write('TaskDuration(sec): ' + str(TaskDur) + "\n")
                Writer_TouchEventTxt.write('Delay: ' + str(Iti) + " sec\n")
                Writer_TouchEventTxt.write('MaxCorrectNum: '+str(MaxCorrectNum)+"\n")
                Writer_TouchEventTxt.write('MaxTrialNum: ' + str(MaxTrialNum) + "\n")
                Writer_TouchEventTxt.write('TimeLimit: ' + str(TimeLimit) + " min\n")
                Writer_TouchEventTxt.write('PunishDur: ' + str(PunishDur) + " sec\n")
                Writer_TouchEventTxt.write('LickDur: ' + str(LickDur) + " sec\n")
                Writer_TouchEventTxt.write('DelayAllowFactor: ' + str(DelayAllowFactor) + " %\n")
                Writer_TouchEventTxt.write('RateTh: ' + str(RateTh) + " %\n")
                Writer_TouchEventTxt.write('DayTh: ' + str(DayTh) + " day\n")
                Writer_TouchEventTxt.write('NextTask: ' + str(NextTask) + "\n")
                Writer_TouchEventTxt.write('CorrectPos: ' + str(CorrectPos) + "\n")
                Writer_TouchEventTxt.write('PanelType: ' + str(PanelType) + "\n")
                Writer_TouchEventTxt.write('WaterCueType: ' + str(WaterCueType) + "\n")
                Writer_TouchEventTxt.write('PunishLight: ' + str(PunishWithLight) + "\n")
                Writer_TouchEventTxt.write('RecordFPS: ' + str(GetRecordFps()) + "\n")
                Writer_TouchEventTxt.write('AWS: ' + AwsOn + "\n")
                Writer_TouchEventTxt.write('AWS_Latency: ' + str(AWS_Latency) + "\n")
                Writer_TouchEventTxt.write(GetRoiSensitivity() + "\n")
                Writer_TouchEventTxt.write(GetServoAngle() + "\n")

                Writer_TouchEventTxt.close()
                Writer_TouchEventCsv.close()
                EndLickRecording()

                SendMail(DeviceNameVar.get() + ' finished task '+str(GetTaskID())+'. Correct:' + str(CorrectNum) + ' Incorrect:' + str(IncorrectNum) + ' Correct:'+str(CorrectRate)+'% Dur:' + str(round(Timer_GetSec(5) / 60,1)) + ' min', 'The task is finished.')

                if IsHousingAnalysis == 1:  #
                    # Update condition of experiment
                    if DatPhase == 0:   # If it is acquisition phase
                        if CorrectRate >= RateTh:   # If correct rate excceeded the criteria
                            ThClearDay+=1   # Increase the criteria counter
                            print("Current cleared stream days:" + str(ThClearDay))
                            if ThClearDay >= DayTh: # If acquisition is completed
                                DatPhase = 1    # Go to the delayed phase
                                print("Delayed phase is started")
                        if CorrectRate < RateTh:  # If correct rate belowed the criteria
                            ThClearDay =0   # Reset the criteria counter
                    if DatPhase == 1:   # If it is delayed phase
                        CurrDelayID += 1 # Change delay
                        if CurrDelayID==1:
                            print("Next delay is "+Delay1Var.get()+" sec")
                        if CurrDelayID==2:
                            print("Next delay is "+Delay2Var.get()+" sec")
                        if CurrDelayID==3:
                            print("Next delay is "+Delay3Var.get()+" sec")
                        if CurrDelayID==4:
                            print("Next delay is "+Delay4Var.get()+" sec")
                        if CurrDelayID==5:
                            print("Next delay is "+Delay5Var.get()+" sec")
                        if CurrDelayID==6:
                            print("Next delay is "+Delay6Var.get()+" sec")
                        if CurrDelayID==7:
                            print("Next delay is "+Delay7Var.get()+" sec")
                        if CurrDelayID==8:
                            print("Next delay is "+Delay8Var.get()+" sec")
                        if CurrDelayID==9:
                            print("Next delay is "+Delay9Var.get()+" sec")
                        if Phase2 == -1:
                            if CurrDelayID > NumOfDelayID-1:    # If the last delayed session is finished (This task is completed)
                                SwitchTask(NextTask)  # Onset task switch trigger
                                print("Task is switched to task#" + str(NextTask) + "  " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

                if IsHousingAnalysis == 0:
                    RoofLightOn()

                Phase = 1  # Go back to the task-waiting phase
                Phase2 = 0
                Phase2_Init = 0
            SetDispVariable(0, 'Phase2', str(Phase2))  # Display "Phase2" value on the main window
    return

def Task9():    # Pattern separation
    global Phase
    Phase0_Init = 0
    Phase1_Init = 0
    Phase2_Init = 0
    while EndFlag == 0:
        OperantHouseUpdate()
        if GetBackButtonStat()==1:    # If "Back" button is clicked
            break   # Back to the task select phase
        if Phase == 0:  # Parameter inputs
            if Phase0_Init == 0:
                # Make GUI for the setting of the parameters for this task
                RemoveMainRightWidget()  # Remove task buttons
                PutStartBackButton()  # Put start/back buttons

                ColumnWidth = 14
                Row = 0  # Begin a new line
                Column = 0
                mMaxCorrectNum = ttk.Label(MainWindowRightFrame, text='MaxCorrectNum', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                MaxCorrectNumVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iMaxCorrectNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxCorrectNumVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mMaxTrialNum = ttk.Label(MainWindowRightFrame, text='MaxTrialNum', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                MaxTrialNumVar = IntVar(MainWindowRoot)
                iMaxTrialNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxTrialNumVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mTimeLimit = ttk.Label(MainWindowRightFrame, text='TimeLimit(min)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                TimeLimitVar = DoubleVar(MainWindowRoot)
                iTimeLimit = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mPunishDur = ttk.Label(MainWindowRightFrame, text='PunishDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                PunishDurVar = DoubleVar(MainWindowRoot)
                iPunishDur = ttk.Entry(MainWindowRightFrame, textvariable=PunishDurVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mIti = ttk.Label(MainWindowRightFrame, text='ITI(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                ItiVar = DoubleVar(MainWindowRoot)
                iIti = ttk.Entry(MainWindowRightFrame, textvariable=ItiVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mLickDur = ttk.Label(MainWindowRightFrame, text='LickDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                LickDurVar = DoubleVar(MainWindowRoot)
                iLickDur = ttk.Entry(MainWindowRightFrame, textvariable=LickDurVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mNextTaskTh = ttk.Label(MainWindowRightFrame, text='NextTaskTh(Correct%)', width=20).grid(row=Row, column=Column, sticky=W)    # Put label
                NextTaskThVar = DoubleVar(MainWindowRoot)
                iNextTaskTh = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskThVar, width=20).grid(row=Row+1, column=Column)  # Place entry field

                Row += 2  # Begin a new line
                Column = 0

                mNextTask = ttk.Label(MainWindowRightFrame, text='NextTask#', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                NextTaskVar = IntVar(MainWindowRoot)
                iNextTask = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mEvalCorrectNum = ttk.Label(MainWindowRightFrame, text='EvalCorrectNum', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                EvalCorrectNumVar = IntVar(MainWindowRoot)
                iEvalCorrectNum = ttk.Entry(MainWindowRightFrame, textvariable=EvalCorrectNumVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mNecCorrectNum = ttk.Label(MainWindowRightFrame, text='NecCorrectNum', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                NecCorrectNumVar = IntVar(MainWindowRoot)
                iNecCorrectNum = ttk.Entry(MainWindowRightFrame, textvariable=NecCorrectNumVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field

                Row += 2  # Begin a new line
                Column = 0

                mCorrectPos = ttk.Label(MainWindowRightFrame, text='CorrectPos', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                CorrectPosVar = StringVar(MainWindowRightFrame)  # Declare variable receiving value from the entry field
                tCorrectPos = OptionMenu(MainWindowRightFrame, CorrectPosVar, "0", "1", "2", "3").grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mPanelType = ttk.Label(MainWindowRightFrame, text='PanelType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                PanelTypeVar = StringVar(MainWindowRightFrame)
                tPanelType = OptionMenu(MainWindowRightFrame, PanelTypeVar, "Normal", "Blink", "Textured").grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mWaterCueType = ttk.Label(MainWindowRightFrame, text='WaterCueType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                WaterCueTypeVar = StringVar(MainWindowRightFrame)
                tWaterCueType = OptionMenu(MainWindowRightFrame, WaterCueTypeVar, "Normal", "Blink").grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mPunishWithLight = ttk.Label(MainWindowRightFrame, text='PunishLight', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                PunishWithLightVar = StringVar(MainWindowRightFrame)
                tPunishWithLight = OptionMenu(MainWindowRightFrame, PunishWithLightVar, "ON", "OFF").grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mAutoDisAltMode = ttk.Label(MainWindowRightFrame, text='AutoDisAltMode', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                AutoDisAltModeVar = StringVar(MainWindowRightFrame)
                iAutoDisAltMode = OptionMenu(MainWindowRightFrame, AutoDisAltModeVar, "ON", "OFF").grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mAwsOn = ttk.Label(MainWindowRightFrame, text='AWS', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                AwsOnVar = StringVar(MainWindowRightFrame)
                iAwsOn = OptionMenu(MainWindowRightFrame, AwsOnVar, "ON", "OFF").grid(row=Row+1, column=Column)  # Place entry field

                Str = "ParametersForTask" + str(GetTaskID())
                if os.path.exists(Str + '/MaxCorrectNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxCorrectNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxCorrectNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxCorrectNumVar.set(150)  # Default value

                if os.path.exists(Str + '/MaxTrialNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxTrialNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxTrialNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxTrialNumVar.set(999)  # Default value

                if os.path.exists(Str + '/TimeLimit.dat') == True:  # If save file exists
                    with open(Str + '/TimeLimit.dat', 'rb') as PickleInst[GetTaskID()]:
                        TimeLimitVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    TimeLimitVar.set(360)  # Default value

                if os.path.exists(Str + '/PunishDur.dat') == True:  # If save file exists
                    with open(Str + '/PunishDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishDurVar.set(5)  # Default value

                if os.path.exists(Str + '/Iti.dat') == True:  # If save file exists
                    with open(Str + '/Iti.dat', 'rb') as PickleInst[GetTaskID()]:
                        ItiVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    ItiVar.set(5)  # Default value
                if os.path.exists(Str + '/LickDur.dat') == True:  # If save file exists
                    with open(Str + '/LickDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        LickDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    LickDurVar.set(2)  # Default value
                if os.path.exists(Str + '/NextTaskTh.dat') == True:  # If save file exists
                    with open(Str + '/NextTaskTh.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskThVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskThVar.set(999)  # Default value
                if os.path.exists(Str + '/NextTask.dat') == True:  # If save file exists
                    with open(Str + '/NextTask.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskVar.set(9)  # Default value
                if os.path.exists(Str + '/EvalCorrectNum.dat') == True:  # If save file exists
                    with open(Str + '/EvalCorrectNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        EvalCorrectNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    EvalCorrectNumVar.set(8)  # Default value
                if os.path.exists(Str + '/NecCorrectNum.dat') == True:  # If save file exists
                    with open(Str + '/NecCorrectNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        NecCorrectNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NecCorrectNumVar.set(7)  # Default value
                if os.path.exists(Str + '/CorrectPos.dat') == True:  # If save file exists
                    with open(Str + '/CorrectPos.dat', 'rb') as PickleInst[GetTaskID()]:
                        CorrectPosVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    CorrectPosVar.set(0)  # Default value
                if os.path.exists(Str + '/PanelType.dat') == True:  # If save file exists
                    with open(Str + '/PanelType.dat', 'rb') as PickleInst[GetTaskID()]:
                        PanelTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PanelTypeVar.set('Normal')  # Default value
                if os.path.exists(Str + '/WaterCueType.dat') == True:  # If save file exists
                    with open(Str + '/WaterCueType.dat', 'rb') as PickleInst[GetTaskID()]:
                        WaterCueTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    WaterCueTypeVar.set('Blink')  # Default value
                if os.path.exists(Str + '/PunishWithLight.dat') == True:  # If save file exists
                    with open(Str + '/PunishWithLight.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishWithLightVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishWithLightVar.set('ON')  # Default value
                if os.path.exists(Str + '/AutoDisAltMode.dat') == True:  # If save file exists
                    with open(Str + '/AutoDisAltMode.dat', 'rb') as PickleInst[GetTaskID()]:
                        AutoDisAltModeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    AutoDisAltModeVar.set('ON')  # Default value
                if os.path.exists(Str + '/AwsOn.dat') == True:  # If save file exists
                    with open(Str + '/AwsOn.dat', 'rb') as PickleInst[GetTaskID()]:
                        AwsOnVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    AwsOnVar.set('OFF')  # Default value

                RemoveAllRoiGui()
                PutRoiGui(0, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)  ROI 19 is water ROI
                PutRoiGui(1, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)  ROI 19 is water ROI
                PutRoiGui(2, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)  ROI 19 is water ROI
                PutRoiGui(3, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)  ROI 19 is water ROI
                PutRoiGui(19, 0, 0, 1)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)  ROI 19 is water ROI

                RemoveAllDigitalOutGui()
                PutDigitalOutGui(10)
                PutDigitalOutGui(12)
                PutDigitalOutGui(13)

                RemoveAllServoGui()
                PutServoGui(3)

                Phase0_Init = 1

        if GetSaveTrgStat() == 1:  # If save trigger is on
            # Parameters of each task are saved into different folder
            Str = "ParametersForTask" + str(GetTaskID())  # Path to the folder for saving of parameters
            if os.path.exists(Str) == False:  # If folder for saving parameters is not exist
                os.mkdir(Str)  # Make folder for saving
            with open(Str + '/MaxCorrectNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxCorrectNumVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/MaxTrialNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxTrialNumVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/TimeLimit.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TimeLimitVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/PunishDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishDurVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Iti.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(ItiVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/LickDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(LickDurVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/NextTask.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/NextTaskTh.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskThVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/EvalCorrectNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(EvalCorrectNumVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/NecCorrectNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NecCorrectNumVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/CorrectPos.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(CorrectPosVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/PanelType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PanelTypeVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/WaterCueType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(WaterCueTypeVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/PunishWithLight.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishWithLightVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/AutoDisAltMode.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(AutoDisAltModeVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/AwsOn.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(AwsOnVar.get(), PickleInst[GetTaskID()])  # Save

        if Phase == 1:  # Wait for starting of task
            if Phase1_Init == 0:
                PutPreTaskButton()
                mStatusVar = StringVar(MainWindowRoot)
                mStatus = ttk.Label(MainWindowRightFrame, textvariable=mStatusVar)
                mStatus.place(x=10, y=0)
                mOngoingResultVar = StringVar(MainWindowRoot)
                Phase1_Init = 1
            mStatusVar.set('Pattern separation task (' + str(GetTaskID()) + ')    Waiting...')
            if IsStartTime()==1:
                StartNow()
        if Phase == 2:  # During task
            if Phase2_Init == 0:  # Initialization of the task
                PutEndTaskNowButton()
                mStatusVar.set('Pattern separation task (' + str(GetTaskID()) + ')    Start time ' + str(TaskStartedMonth) + '/' + str(TaskStartedDay) + ' ' + str(TaskStartedHour) + ':' + str(TaskStartedMinute) + '    Running')
                mOngoingResult = ttk.Label(MainWindowRightFrame, textvariable=mOngoingResultVar)
                mOngoingResult.place(x=10, y=18)

                # Convert StringVars of parameters into integer or normal string to use in the following
                MaxCorrectNum = int(MaxCorrectNumVar.get())
                MaxTrialNum = int(MaxTrialNumVar.get())
                TimeLimit = float(TimeLimitVar.get())
                PunishDur = float(PunishDurVar.get())
                Iti = float(ItiVar.get())
                LickDur = float(LickDurVar.get())
                NextTask = int(NextTaskVar.get())
                NextTaskTh = float(NextTaskThVar.get())
                EvalCorrectNum = int(EvalCorrectNumVar.get())
                NecCorrectNum = int(NecCorrectNumVar.get())

                CorrectPos = int(CorrectPosVar.get())
                PanelType = PanelTypeVar.get()
                WaterCueType = WaterCueTypeVar.get()
                PunishWithLight = PunishWithLightVar.get()
                AutoDisAltMode = AutoDisAltModeVar.get()
                AwsOn = AwsOnVar.get()

                StartLickRecording()
                RoofLightOff()
                InfraredLightOn()
                if WaterCueType == 'Normal':
                    DigitalOutOn(10)
                if WaterCueType == 'Blink':
                    DigitalOutBlinkOn(10)
                ServoPosInside(3)
                if PanelType == 'Normal':
                    CreateNormalPanel(0)
                    CreateNormalPanel(1)
                    CreateNormalPanel(2)
                    CreateNormalPanel(3)
                if PanelType == 'Blink':
                    CreateBlinkPanel(0)
                    CreateBlinkPanel(1)
                    CreateBlinkPanel(2)
                    CreateBlinkPanel(3)
                if PanelType == 'Textured':
                    CreateTexturedPanel(0,0)
                    CreateTexturedPanel(1,0)
                    CreateTexturedPanel(2,0)
                    CreateTexturedPanel(3,0)

                # Declar local variables for this task
                TouchNum = 0
                CorrectNum = 0
                IncorrectNum = 0
                AdmittedCorrectNum = 0
                AdmittedIncorrectNum = 0
                AdmittedTouchNum = 0
                AdmittedCorrectRate= 0
                ResultLog=[0]*EvalCorrectNum
                ReversalNum=0
                TrialPerReversal=0  # Average trial number per reversal
                TaskDur = 0

                LightCycleControlOff()
                DoneCorrectResponse = 1
                NowDrinking = 0
                NowPunishing = 0
                AWS_Latency = 20
                StartRecording()  # Start camera capturing and sending of TTL

                TrialNum = 0

                Timer_Start(5)  # Task time limit timer start
                Phase2 = 2
                Phase2_Init = 1

                Writer_TouchEventTxt = open(
                    Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) +  " Touch.txt",
                    'w')  # Initialize the text exporter
                Writer_TouchEventCsv = open(
                    Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) +  " Touch.csv",
                    'w')  # Initialize the text exporter
                Writer_TouchEventTxt.write('TrialNum\tResult\t\t\tyyyy/mm/dd\th:m\ts\n')  # Write item name
                print("Task #" + str(Task) + " is started at " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(
                    GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

            if Phase2 == 0:  # Initiation of new trial
                TaskDur = Timer_GetSec(5)
                DoneCorrectResponse = 0
                TrialNum += 1
                if CorrectPos==0 or CorrectPos==3:
                    ShowPanel(0)
                    ShowPanel(3)
                if CorrectPos==1 or CorrectPos==2:
                    ShowPanel(1)
                    ShowPanel(2)
                Timer_Start(0)  # Start the latency timer
                Phase2 += 1
            if Phase2 == 1:  # Panel presentation
                TouchedPanelID = DetectRoiNosepoke()  # Examine which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID != -1 and TouchedPanelID != 19:    # If mouse touchs any panel
                    if TouchedPanelID == int(CorrectPos):  # If mouse touches correct panel
                        DoneCorrectResponse = 1
                        ServoPosInside(3)  # Move water nozzle to the inside position
                        # DigitalOutOn(10)
                        NowDrinking = 0
                        CorrectNum += 1  # Increase the number of correct response
                        TouchNum += 1
                        for i in range(EvalCorrectNum-1):
                            ResultLog[EvalCorrectNum-1-i]=ResultLog[EvalCorrectNum-1-i-1]   # Push the log
                        ResultLog[0] = 1    # Input current result
                        if  AdmittedTouchNum>0:
                            AdmittedCorrectRate = round(AdmittedCorrectNum/AdmittedTouchNum*100,2)
                        if ReversalNum > 0:
                            TrialPerReversal=round(AdmittedTouchNum/ReversalNum,2)
                        mOngoingResultVar.set(
                            'TotalCorrect:' + str(CorrectNum) + '  TotalIncorrect:' + str(IncorrectNum) + '  Total:' + str(TouchNum) + ' | AdmittedCorrect:' + str(AdmittedCorrectNum) + '  AdmittedIncorrect:' + str(AdmittedIncorrectNum) + '  AdmittedTouch:' + str(AdmittedTouchNum) + '  AdmittedCorrect:' + str(AdmittedCorrectRate) +' %'+ '  Reversal:'+str(ReversalNum)+'  Touch/Reversal:'+str(TrialPerReversal))
                        Writer_TouchEventTxt.write(
                            str(TrialNum) + '\tPanelTouched(Correct)\t' +str(TouchedPanelID)+'\t'+ str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(
                            str(TrialNum) + ',1,' +str(TouchedPanelID)+','+ str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                        HidePanel(0)
                        HidePanel(1)
                        HidePanel(2)
                        HidePanel(3)
                        Timer_End(0)
                        if WaterCueType == 'Normal':
                            DigitalOutOn(10)
                        if WaterCueType == 'Blink':
                            DigitalOutBlinkOn(10)
                        Phase2 = 2  # Start reward phase
                    if TouchedPanelID != int(CorrectPos):  # If mouse touchs correct panel
                        ServoPosOutside(3)
                        if PunishWithLight == 'ON':
                            RoofLightOn()  # Turn on roof light
                        IncorrectNum += 1
                        TouchNum += 1
                        for i in range(EvalCorrectNum-1):
                            ResultLog[EvalCorrectNum-1-i]=ResultLog[EvalCorrectNum-1-i-1]  # Push the log
                        ResultLog[0] = 0
                        if  AdmittedTouchNum>0:
                            AdmittedCorrectRate = round(AdmittedCorrectNum/AdmittedTouchNum*100,2)
                        if ReversalNum > 0:
                            TrialPerReversal=round(AdmittedTouchNum/ReversalNum, 2)
                        mOngoingResultVar.set(
                            'TotalCorrect:' + str(CorrectNum) + '  TotalIncorrect:' + str(IncorrectNum) + '  Total:' + str(TouchNum) + ' | AdmittedCorrect:' + str(AdmittedCorrectNum) + '  AdmittedIncorrect:' + str(AdmittedIncorrectNum) + '  AdmittedTouch:' + str(AdmittedTouchNum) + '  AdmittedCorrect:' + str(AdmittedCorrectRate) +' %'+ '  Reversal:'+str(ReversalNum)+'  Touch/Reversal:'+str(TrialPerReversal))
                        Writer_TouchEventTxt.write(
                            str(TrialNum) + '\tPanelTouched(Wrong)\t' +str(TouchedPanelID)+'\t'+ str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(
                            str(TrialNum) + ',0,' +str(TouchedPanelID)+','+ str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                        HidePanel(0)
                        HidePanel(1)
                        HidePanel(2)
                        HidePanel(3)
                        Timer_End(0)  # End timer1
                        Timer_Start(0)  # Start punish timer
                        Phase2 = 5  # Start punishment phase
                if Timer_GetSec(5) >= TimeLimit * 60:   # If time limit is exceeded
                    TaskDur = Timer_GetSec(5)
                    Timer_End(5)
                    Phase2 = 6
            if Phase2 == 2:  # Reward phase
                if DetectRoiNosepoke() == 19 and NowDrinking == 0:  # If the mouse initiates nose poke
                    NowDrinking = 1
                    Timer_Start(0)  # Start lick timer
                if NowDrinking == 1:
                    if DoneCorrectResponse == 1 and Timer_GetSec(0) >= LickDur:  # If lick time exceed the designated time
                        Timer_End(0)  # End lick timer
                        ServoPosMiddle(3)  # Move water nozzle to the intermediate position
                        DigitalOutOff(10)
                        NowDrinking = 0
                        Timer_Start(0)  # Start ITI timer
                        Phase2 = 3

            if Phase2 == 3:  # ITI
                if Timer_GetSec(0) >= Iti:  # If ITI is passed
                    Timer_End(0)
                    # Count recent correct num (Evaluate latest EvaCorrectNum trials)
                    RecentCorrectNum=0
                    for i in range(EvalCorrectNum):
                        if ResultLog[i]==1:
                            RecentCorrectNum+=1
                    if RecentCorrectNum >= NecCorrectNum:
                        ReversalNum += 1
                        AdmittedCorrectNum = CorrectNum
                        AdmittedIncorrectNum = IncorrectNum
                        AdmittedTouchNum = AdmittedCorrectNum + AdmittedIncorrectNum
                        if AdmittedTouchNum>0:
                            AdmittedCorrectRate = round(AdmittedCorrectNum/AdmittedTouchNum*100,2)
                        if ReversalNum > 0:
                            TrialPerReversal=round(AdmittedTouchNum/ReversalNum,2)
                        mOngoingResultVar.set('TotalCorrect:' + str(CorrectNum) + '  TotalIncorrect:' + str(IncorrectNum) + '  Total:' + str(TouchNum) + ' | AdmittedCorrect:' + str(
                            AdmittedCorrectNum) + '  AdmittedIncorrect:' + str(AdmittedIncorrectNum) + '  AdmittedTouch:' + str(AdmittedTouchNum) + '  AdmittedCorrect:' + str(
                            AdmittedCorrectRate) + ' %' + '  Reversal:' + str(ReversalNum) + '  Touch/Reversal:' + str(TrialPerReversal))
                        for i in range(EvalCorrectNum):
                            ResultLog[i] = 0
                        Trg=0
                        if CorrectPos==0:
                            CorrectPos=3
                            Trg=1
                        if CorrectPos==3 and Trg==0:
                            CorrectPos=0
                            Trg=1
                        if CorrectPos==1 and Trg==0:
                            CorrectPos=2
                            Trg=1
                        if CorrectPos==2 and Trg==0:
                            CorrectPos=1
                            Trg=1
                    Phase2 = 0  # Go to the next trial
                if CorrectNum >= MaxCorrectNum or TouchNum >= MaxTrialNum:  # If mouse achieved criteria of finishing the task
                    Timer_End(5)
                    ServoPosMiddle(3)
                    DigitalOutOff(10)
                    if AutoDisAltMode=='ON':    # Switch distance for the next session (For housing analysis)
                        Trg = 0
                        if CorrectPos == 0:
                            CorrectPos = 1
                            Trg = 1
                        if CorrectPos == 3 and Trg == 0:
                            CorrectPos = 2
                            Trg = 1
                        if CorrectPos == 1 and Trg == 0:
                            CorrectPos = 0
                            Trg = 1
                        if CorrectPos == 2 and Trg == 0:
                            CorrectPos = 3
                            Trg = 1
                        with open(Str + '/CorrectPos.dat', 'wb') as PickleInst[GetTaskID()]:
                            pickle.dump(str(CorrectPos), PickleInst[GetTaskID()])  # Save
                    Timer_Start(0)  # Timer for interval between task and arbitary water supply is started
                    Phase2 = 6  # Go to the AWS
            if Phase2 == 5:  # Punishment phase
                if Timer_GetSec(0) >= PunishDur:  # If punishment time is passed
                    RoofLightOff()
                    NowPunishing = 0
                    ServoPosMiddle(3)  # Move water nozzle to the intermediate position
                    Timer_End(0)  # End punishment timer1
                    Timer_Start(0)  # Start ITI timer
                    Phase2 = 3
            if Phase2 == 6:
                HidePanel(0)
                HidePanel(1)
                HidePanel(2)
                HidePanel(3)
                if CorrectNum < MaxCorrectNum and AwsOn=='ON':  # If mouse didn't achieved the max correct response
                    Timer_Start(0)
                    Phase2 = 7
                if CorrectNum == MaxCorrectNum or AwsOn=='OFF':  # If mouse achieved the max correct response
                    Phase2 = -1
            if Phase2 == 7:  # Wait until arbitary water suuply is started
                if Timer_GetSec(0) >= AWS_Latency:  # If the interval is past 60
                    Timer_End(0)
                    ArbitaryWaterSupplyDur = (MaxCorrectNum - CorrectNum) * LickDur * 1000  # Caliculate duration of complement water supply
                    if WaterCueType == 'Normal':
                        StartArbitaryWaterSupply(3,10,0,ArbitaryWaterSupplyDur) # Start complement water supply
                    if WaterCueType == 'Blink':
                        StartArbitaryWaterSupply(3,10,1,ArbitaryWaterSupplyDur) # Start complement water supply
                    Phase2 = 8
            if Phase2 == 8:
                if GetArbitaryWaterSupplyStat() == 1:  # If complement water supply is finished
                    Phase2 = -1

            if Phase2 == -1 or GetEndTaskNowButtonStat() == 1:  # Task finish phase
                LightCycleControlOn()
                ServoPosMiddle(3)
                # if Panel!=null:
                DeleteAllPanel()
                InfraredLightOff()
                NowPunishing = 0
                if GetRecordingStat() == 1:
                    SetEndRecordingTimer(60)
                if CorrectNum > 0 or IncorrectNum > 0:
                    Writer_TouchEventTxt.write('Correct num:' + str(CorrectNum) + '  Incorrect num:' + str(IncorrectNum) +'  TouchNum:' + str(TouchNum) +  '  AdmittedCorrect num:' + str(AdmittedCorrectNum) + '  AdmittedIncorrect num:' + str(AdmittedIncorrectNum) +'  AdmittedTouchNum:' + str(AdmittedTouchNum) + '  Correct rate' + str(
                        AdmittedCorrectRate) + '%  Reversal:'+str(ReversalNum)+'  Touch/Reversal:'+str(TrialPerReversal) + "\n")  # Summary of result
                Writer_TouchEventTxt.write('SessionStartTime: ' +str(GetTaskStartedMonth())+'/'+ str(GetTaskStartedDay()) +' '+str(GetTaskStartedHour())+':'+str(GetTaskStartedMinute())+':'+str(GetTaskStartedSecond())+ "\n")
                Writer_TouchEventTxt.write('SessionEndTime: ' +str(TimeNow.month)+'/'+ str(TimeNow.day) +' '+str(TimeNow.hour)+':'+str(TimeNow.minute)+':'+str(TimeNow.second+(TimeNow.microsecond//1000)/1000)+ "\n")
                Writer_TouchEventTxt.write('TaskDuration(sec): ' + str(TaskDur) + "\n")
                Writer_TouchEventTxt.write('MaxCorrectNum: ' + str(MaxCorrectNum) + "\n")
                Writer_TouchEventTxt.write('MaxTrialNum: ' + str(MaxTrialNum) + "\n")
                Writer_TouchEventTxt.write('TimeLimit: ' + str(TimeLimit) + "\n")
                Writer_TouchEventTxt.write('PunishDur: ' + str(PunishDur) + "\n")
                Writer_TouchEventTxt.write('Iti: ' + str(Iti) + "\n")
                Writer_TouchEventTxt.write('LickDur: ' + str(LickDur) + "\n")
                Writer_TouchEventTxt.write('NextTask: ' + str(NextTask) + "\n")
                Writer_TouchEventTxt.write('NextTaskTh: ' + str(NextTaskTh) + "\n")
                Writer_TouchEventTxt.write('EvalCorrectNum: ' + str(EvalCorrectNum) + "\n")
                Writer_TouchEventTxt.write('NecCorrectNum: ' + str(NecCorrectNum) + "\n")
                Writer_TouchEventTxt.write('CorrectPos: ' + str(CorrectPosVar.get()) + "\n")
                Writer_TouchEventTxt.write('PanelType: ' + str(PanelType) + "\n")
                Writer_TouchEventTxt.write('WaterCueType: ' + str(WaterCueType) + "\n")
                Writer_TouchEventTxt.write('PunishLight: ' + str(PunishWithLight) + "\n")
                Writer_TouchEventTxt.write('AutoDisAltMode: ' + str(AutoDisAltMode) + "\n")
                Writer_TouchEventTxt.write('AWS: ' + AwsOn + "\n")
                Writer_TouchEventTxt.write('AWS_Latency : ' + str(AWS_Latency) + "\n")
                Writer_TouchEventTxt.write('RecordFPS: ' + str(GetRecordFps()) + "\n")
                Writer_TouchEventTxt.write(GetRoiSensitivity() + "\n")
                Writer_TouchEventTxt.write(GetServoAngle() + "\n")
                Writer_TouchEventTxt.close()
                Writer_TouchEventCsv.close()
                EndLickRecording()
                SendMail(DeviceNameVar.get() + ' finished task ' + str(GetTaskID()) + '. Correct:' + str(CorrectNum) + ' Incorrect:' + str(IncorrectNum) + ' Touch/Reversal:' + str(TrialPerReversal) + '% Dur:' + str(round(Timer_GetSec(5) / 60,1)) + ' min', 'The task is finished')

                if IsHousingAnalysis == 1 and Phase2 == -1:  # If it is housing analysis
                    if AdmittedCorrectRate >= NextTaskTh:  # If the score exceed the criteria to switch the next task
                        SwitchTask(NextTask)  # Onset task switch trigger
                        print("Task is switched to task#" + str(NextTask) + "  " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

                if IsHousingAnalysis == 0:
                    RoofLightOn()
                Phase = 1  # Go back to the task-waiting phase
                Phase2 = 0
                Phase2_Init = 0
            SetDispVariable(0, 'Phase2', str(Phase2))  # Display "Phase2" value on the main window
    return


def Task10():   # Patttern separation (TUNL/DNMTP)
    global Phase
    Phase0_Init=0
    Phase1_Init=0
    Phase2_Init=0
    while EndFlag==0:
        OperantHouseUpdate()
        if GetBackButtonStat()==1:    # If "Back" button is clicked
            break   # Back to the task select phase
        if Phase == 0:  # Parameter inputs
            if Phase0_Init == 0:
                # Make GUI for the setting of the parameters for this task
                RemoveMainRightWidget() # Remove task buttons
                PutStartBackButton()    # Put start/back buttons

                ColumnWidth = 14
                Row = 0  # Begin a new line
                Column = 0
                mMaxCorrectNum = ttk.Label(MainWindowRightFrame, text='MaxCorrect', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                MaxCorrectNumVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iMaxCorrectNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxCorrectNumVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mMaxTrialNum = ttk.Label(MainWindowRightFrame, text='MaxTrial', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                MaxTrialNumVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iMaxTrialNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxTrialNumVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mTimeLimit = ttk.Label(MainWindowRightFrame, text='TimeLimit(m)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                TimeLimitVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iTimeLimit = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mPunishDur = ttk.Label(MainWindowRightFrame, text='PunishDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                PunishDurVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iPunishDur = ttk.Entry(MainWindowRightFrame, textvariable=PunishDurVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mSampleRewardRate = ttk.Label(MainWindowRightFrame, text='S_Reward%', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                SampleRewardRateVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iSampleRewardRate = ttk.Entry(MainWindowRightFrame, textvariable=SampleRewardRateVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mSampleLickDur = ttk.Label(MainWindowRightFrame, text='S_LickDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                SampleLickDurVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iSampleLickDur = ttk.Entry(MainWindowRightFrame, textvariable=SampleLickDurVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mChoiceLickDur = ttk.Label(MainWindowRightFrame, text='C_LickDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                ChoiceLickDurVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iChoiceLickDur = ttk.Entry(MainWindowRightFrame, textvariable=ChoiceLickDurVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mIti = ttk.Label(MainWindowRightFrame, text='ITI(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                ItiVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iIti = ttk.Entry(MainWindowRightFrame, textvariable=ItiVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field

                Row += 2  # Begin a new line
                Column = 0

                mDelayAllowFactor = ttk.Label(MainWindowRightFrame, text='ValidDelay%', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                DelayAllowFactorVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelayAllowFactor = ttk.Entry(MainWindowRightFrame, textvariable=DelayAllowFactorVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mSeed = ttk.Label(MainWindowRightFrame, text='Seed', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                SeedVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iSeed = ttk.Entry(MainWindowRightFrame, textvariable=SeedVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mDayTh = ttk.Label(MainWindowRightFrame, text='DayTh', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                DayThVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDayTh = ttk.Entry(MainWindowRightFrame, textvariable=DayThVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mNextTask = ttk.Label(MainWindowRightFrame, text='NextTask', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                NextTaskVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iNextTask = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field

                Row += 2  # Begin a new line
                Column = 0

                mTaskType = ttk.Label(MainWindowRightFrame, text='TaskType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                TaskTypeVar = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                tTaskType = OptionMenu(MainWindowRightFrame, TaskTypeVar, "Pre", "TUNL", "TUNL(L)", "TUNL(S)").grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mCorrectionTrial = ttk.Label(MainWindowRightFrame, text='Correction', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                CorrectionTrialVar = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                tCorrectionTrial = OptionMenu(MainWindowRightFrame, CorrectionTrialVar, "OFF", "WithinTrial","NextTrial").grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mWaterCueType = ttk.Label(MainWindowRightFrame, text='WaterCue', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                WaterCueTypeVar = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                tWaterCueType = OptionMenu(MainWindowRightFrame, WaterCueTypeVar, "Normal", "Blink").grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mPunishWithLight = ttk.Label(MainWindowRightFrame, text='PunishLight', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                PunishWithLightVar = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                tPunishWithLight = OptionMenu(MainWindowRightFrame, PunishWithLightVar, "ON", "OFF").grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mAwsOn = ttk.Label(MainWindowRightFrame, text='AWS', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                AwsOnVar = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                tAwsOn = OptionMenu(MainWindowRightFrame, AwsOnVar, "ON", "OFF").grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mDelay = ttk.Label(MainWindowRightFrame, text='Delay(sec)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                DelayVar = StringVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iDelay = ttk.Entry(MainWindowRightFrame, textvariable=DelayVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field

                Str = "ParametersForTask" + str(GetTaskID())
                if os.path.exists(Str + '/MaxCorrectNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxCorrectNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxCorrectNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxCorrectNumVar.set(80)  # Default value

                if os.path.exists(Str + '/MaxTrialNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxTrialNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxTrialNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxTrialNumVar.set(999)  # Default value

                if os.path.exists(Str + '/TimeLimit.dat') == True:  # If save file exists
                    with open(Str + '/TimeLimit.dat', 'rb') as PickleInst[GetTaskID()]:
                        TimeLimitVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    TimeLimitVar.set(600)  # Default value

                if os.path.exists(Str + '/PunishDur.dat') == True:  # If save file exists
                    with open(Str + '/PunishDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishDurVar.set(10)  # Default value

                if os.path.exists(Str + '/SampleRewardRate.dat') == True:  # If save file exists
                    with open(Str + '/SampleRewardRate.dat', 'rb') as PickleInst[GetTaskID()]:
                        SampleRewardRateVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    SampleRewardRateVar.set(33.33)  # Default value

                if os.path.exists(Str + '/SampleLickDur.dat') == True:  # If save file exists
                    with open(Str + '/SampleLickDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        SampleLickDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    SampleLickDurVar.set(0)  # Default value

                if os.path.exists(Str + '/ChoiceLickDur.dat') == True:  # If save file exists
                    with open(Str + '/ChoiceLickDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        ChoiceLickDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    ChoiceLickDurVar.set(2)  # Default value

                if os.path.exists(Str + '/Iti.dat') == True:  # If save file exists
                    with open(Str + '/Iti.dat', 'rb') as PickleInst[GetTaskID()]:
                        ItiVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    ItiVar.set(0)  # Default value

                if os.path.exists(Str + '/DelayAllowFactor.dat') == True:  # If save file exists
                    with open(Str + '/DelayAllowFactor.dat', 'rb') as PickleInst[GetTaskID()]:
                        DelayAllowFactorVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    DelayAllowFactorVar.set(130)  # Default value

                if os.path.exists(Str + '/Seed.dat') == True:  # If save file exists
                    with open(Str + '/Seed.dat', 'rb') as PickleInst[GetTaskID()]:
                        SeedVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    SeedVar.set(0)  # Default value

                if os.path.exists(Str + '/DayTh.dat') == True:  # If save file exists
                    with open(Str + '/DayTh.dat', 'rb') as PickleInst[GetTaskID()]:
                        DayThVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    DayThVar.set(6)  # Default value

                if os.path.exists(Str + '/NextTask.dat') == True:  # If save file exists
                    with open(Str + '/NextTask.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskVar.set(10)  # Default value
                if os.path.exists(Str + '/TaskType.dat') == True:  # If save file exists
                    with open(Str + '/TaskType.dat', 'rb') as PickleInst[GetTaskID()]:
                        TaskTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    TaskTypeVar.set('Pre')  # Default value

                if os.path.exists(Str + '/CorrectionTrial.dat') == True:  # If save file exists
                    with open(Str + '/CorrectionTrial.dat', 'rb') as PickleInst[GetTaskID()]:
                        CorrectionTrialVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    CorrectionTrialVar.set('OFF')  # Default value

                if os.path.exists(Str + '/WaterCueType.dat') == True:  # If save file exists
                    with open(Str + '/WaterCueType.dat', 'rb') as PickleInst[GetTaskID()]:
                        WaterCueTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    WaterCueTypeVar.set('Normal')  # Default value

                if os.path.exists(Str + '/PunishWithLight.dat') == True:  # If save file exists
                    with open(Str + '/PunishWithLight.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishWithLightVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishWithLightVar.set('ON')  # Default value

                if os.path.exists(Str + '/Delay.dat') == True:  # If save file exists
                    with open(Str + '/Delay.dat', 'rb') as PickleInst[GetTaskID()]:
                        DelayVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    DelayVar.set('1')  # Default value

                if os.path.exists(Str + '/AwsOn.dat') == True:  # If save file exists
                    with open(Str + '/AwsOn.dat', 'rb') as PickleInst[GetTaskID()]:
                        AwsOnVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    AwsOnVar.set('ON')  # Default value

                RemoveAllRoiGui()
                PutRoiGui(0, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(1, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(2, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(3, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(4, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(5, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(6, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(7, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(8, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(9, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(19, 0, 0, 1)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)

                RemoveAllDigitalOutGui()
                PutDigitalOutGui(10)
                PutDigitalOutGui(12)
                PutDigitalOutGui(13)

                RemoveAllServoGui()
                PutServoGui(3)
                Phase0_Init = 1

        if GetSaveTrgStat() == 1:    # If save trigger is on
            # Parameters of each task are saved into different folder
            Str="ParametersForTask"+str(GetTaskID())   # Path to the folder for saving of parameters
            if os.path.exists(Str) == False:    # If folder for saving parameters is not exist
                os.mkdir(Str)   # Make folder for saving
            with open(Str+'/MaxCorrectNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxCorrectNumVar.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/MaxTrialNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxTrialNumVar.get(),PickleInst[GetTaskID()])     # Save
            with open(Str + '/TimeLimit.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TimeLimitVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str+'/PunishDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishDurVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str + '/SampleRewardRate.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(SampleRewardRateVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/SampleLickDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(SampleLickDurVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/ChoiceLickDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(ChoiceLickDurVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Iti.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(ItiVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/DelayAllowFactor.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(DelayAllowFactorVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str+'/Seed.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(SeedVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str + '/DayTh.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(DayThVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/NextTask.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/TaskType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TaskTypeVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/CorrectionTrial.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(CorrectionTrialVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str+'/WaterCueType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(WaterCueTypeVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/PunishWithLight.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishWithLightVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str + '/AwsOn.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(AwsOnVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str+'/Delay.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(DelayVar.get(),PickleInst[GetTaskID()])     # Save

        if Phase == 1:  # Wait for starting of task
            if Phase1_Init == 0:
                PutPreTaskButton()
                mStatusVar = StringVar(MainWindowRoot)
                mStatus = ttk.Label(MainWindowRightFrame, textvariable=mStatusVar)
                mStatus.place(x=10, y=0)
                mOngoingResultVar = StringVar(MainWindowRoot)
                ElapsedDay = 0        # Number of stream days where criteria threshold is achieved
                Phase1_Init = 1
            mStatusVar.set('TUNL pattern sep. task (' + str(GetTaskID()) + ')    Waiting...')
            if IsStartTime() == 1:  # If task start time is arrived
                StartNow()
        if Phase == 2:  # During task
            if Phase2_Init == 0: # Initialization of the task
                PutEndTaskNowButton()

                mStatusVar.set('TUNL pattern sep. task (' + str(GetTaskID()) + ')    Start time ' + str(TaskStartedMonth) + '/' + str(TaskStartedDay) + ' ' + str(TaskStartedHour) + ':' + str(TaskStartedMinute) + '    Running')
                mOngoingResult = ttk.Label(MainWindowRightFrame, textvariable=mOngoingResultVar)
                mOngoingResult.place(x=10, y=18)
                OutResultStringA = ''
                ResultStringA = ''
                ResultStringB = ''
                ValidResultStringA = ''
                ValidResultStringB = ''
                # Convert StringVars of parameters into integer or normal string to use in the following
                MaxCorrectNum=int(MaxCorrectNumVar.get())
                MaxTrialNum = int(MaxTrialNumVar.get())
                TimeLimit = float(TimeLimitVar.get())
                PunishDur = float(PunishDurVar.get())
                SampleRewardRate = float(SampleRewardRateVar.get())
                SampleLickDur = float(SampleLickDurVar.get())
                ChoiceLickDur = float(ChoiceLickDurVar.get())
                Iti = float(ItiVar.get())
                AwsOn=AwsOnVar.get()
                DelayAllowFactor = float(DelayAllowFactorVar.get())
                Seed = int(SeedVar.get())
                DayTh = int(DayThVar.get())
                NextTask = int(NextTaskVar.get())
                TaskType = TaskTypeVar.get()
                CorrectionTrial = CorrectionTrialVar.get()
                WaterCueType = WaterCueTypeVar.get()
                PunishWithLight = PunishWithLightVar.get()
                DelayDur=0
                if DelayVar.get()!="":
                    DelayDur = int(DelayVar.get())

                StartLickRecording()
                RoofLightOff()
                InfraredLightOn()
                if WaterCueType == 'Normal':
                    DigitalOutOn(10)
                if WaterCueType == 'Blink':
                    DigitalOutBlinkOn(10)
                ServoPosInside(3)
                for i in range(10):
                    CreateNormalPanel(i)

                # Declar local variables for this task
                CurrTrialNum = -1
                TotalCorrectNum = 0
                TotalIncorrectNum = 0
                TrialNum = [0 for i in range(2)]
                CorrectNum = [0 for i in range(2)]
                IncorrectNum = [0 for i in range(2)]
                CorrectRate = [0 for i in range(2)]
                MaxPanelPattern = 14    # Enter total number of pannel locations pattern
                PannelPatternNum = [0 for i in range(MaxPanelPattern)]
                SamplePanelNum = [0 for i in range(10)]
                ValidCorrectNum= [0 for i in range(2)]   # Correct touch num which have done within the designated delay
                ValidIncorrectNum = [0 for i in range(2)]
                ValidTouchNum = [0 for i in range(2)]
                ValidCorrectRate= [0 for i in range(2)]  # Correct rate which have done within the designated delay
                TrialHistory=[[-1 for i in range(5)] for j in range(MaxTrialNum)]   # Keeps history of pannel pattern and time of touching (For valid trial selection) p0:PanelPatternID p1:DelayStartTime p2:DelayEndTime p3:Result p4:Separate distance
                DelayHistory = [-1 for i in range(MaxTrialNum)]   # Keeps delay history
                PanelPattern = [[0 for i in range(10)] for j in range(MaxPanelPattern)]    # Keeps positions of panels in each pattern
                PanelPattern[0][0] = 1
                PanelPattern[0][4] = 1
                PanelPattern[1][1] = 1
                PanelPattern[1][9] = 1
                PanelPattern[2][0] = 1
                PanelPattern[2][9] = 1
                PanelPattern[3][3] = 1
                PanelPattern[3][5] = 1
                PanelPattern[4][4] = 1
                PanelPattern[4][5] = 1
                PanelPattern[5][0] = 1
                PanelPattern[5][8] = 1
                PanelPattern[6][5] = 1
                PanelPattern[6][9] = 1
                PanelPattern[7][4] = 1
                PanelPattern[7][6] = 1
                PanelPattern[8][1] = 1
                PanelPattern[8][3] = 1
                PanelPattern[9][5] = 1
                PanelPattern[9][7] = 1
                PanelPattern[10][2] = 1
                PanelPattern[10][4] = 1
                PanelPattern[11][0] = 1
                PanelPattern[11][2] = 1
                PanelPattern[12][6] = 1
                PanelPattern[12][8] = 1
                PanelPattern[13][7] = 1
                PanelPattern[13][9] = 1

                LitPanelID = [0]*2
                SamplePanelID=-1
                CorrectPanelID=-1
                AllowedDelay = 10 + (DelayDur * DelayAllowFactor / 100)  # Caliculate threshold for data selection


                # Make reward list for sample touch
                random.seed(Seed)
                RewardFloatInterval = 1.0/SampleRewardRate*100.0
                print("Reward interval: " + str(RewardFloatInterval))
                TotalRewardNumInCorrectList = int(MaxTrialNum * SampleRewardRate / 100)
                SampleRewardList = [0] * MaxTrialNum  # Keep which correct touch is rewarded or not
                CurrentTrialFloatNum = 0.0
                FailedNum = 0
                for i in range(TotalRewardNumInCorrectList):
                    for i2 in range(5):
                        r = int(CurrentTrialFloatNum + (random.random() * RewardFloatInterval))
                        if SampleRewardList[r] == 0:
                            SampleRewardList[r] = 1
                            break
                        if i2 == 4:
                            FailedNum += 1
                    CurrentTrialFloatNum += RewardFloatInterval
                print("FailedNum:" + str(FailedNum))
                for i in range(FailedNum):
                    while True:
                        r = int(random.random() * MaxTrialNum)
                        if SampleRewardList[r] == 0:
                            SampleRewardList[r] = 1
                            break
                for i in range(MaxTrialNum):
                    print("Sample reward:" + str(SampleRewardList[i]))


                ValidString=['','']
                if TaskType == 'TUNL' or TaskType == 'TUNL(S)':
                    SeparateDistance = 0  # 1:large 0:short
                if TaskType == 'TUNL(L)':
                    SeparateDistance = 1  # 1:large 0:short
                TaskDur = 0   # Actual time elapsed in the session
                LightCycleControlOff()
                DoneCorrectResponse = 1
                WithinTrialCorrection = 0   # If correction trial is took place within the trial
                NowDrinking = 0
                AWS_Latency = 20
                StartRecording()    # Start camera capturing and sending of TTL
                print('Seed: '+str(Seed))
                random.seed(Seed)

                HideTouchCursor()
                Timer_Start(5)  # Task time limit timer start
                Phase2 = 9
                Phase2_Init = 1

                Writer_TouchEventTxt = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(Task) +  " Touch.txt",'w')  # Initialize the text exporter
                Writer_TouchEventCsv = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(Task) +  " Touch.csv",'w')  # Initialize the text exporter
                Writer_TouchEventTxt.write('TrialNum\tResult\tPanel\tyyyy/mm/dd\th:m\ts\tPanelPatternID\tDistance\n')  # Write item name
                print("Task #" + str(GetTaskID()) + " is started at " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

            if Phase2 == 0:  # Initiation of new trial
                TaskDur = Timer_GetSec(5)
                if TaskType == 'TUNL' or TaskType == 'TUNL(L)' or TaskType == 'TUNL(S)':
                    Trg = 0
                    if DoneCorrectResponse == 1 or CorrectionTrial == 'OFF' or CorrectionTrial == 'WithinTrial':
                        while Trg == 0:
                            if SeparateDistance==1:
                                PanelPatternID=int(random.random()*8)
                            if SeparateDistance==0:
                                PanelPatternID=int(random.random()*6)+8
                            Trg = 1
                            if CurrTrialNum > 1:
                                if PanelPatternID == TrialHistory[CurrTrialNum-1][0] and PanelPatternID == TrialHistory[CurrTrialNum-2][0]: # If Correct position is same as previous and pre-previous position
                                    Trg = 0
                        Num=0
                        for i in range(10):
                            if PanelPattern[PanelPatternID][i] == 1:
                                LitPanelID[Num] = i
                                Num+=1
                        Rnd = int(random.random()*2)
                        PreCorrectPanelID = CorrectPanelID
                        if Rnd == 0:
                            SamplePanelID = LitPanelID[0]  # Set sample panel ID in this trial
                            CorrectPanelID = LitPanelID[1]  # Set correct panel ID in this trial
                        if Rnd == 1:
                            SamplePanelID = LitPanelID[1]  # Set sample panel ID in this trial
                            CorrectPanelID = LitPanelID[0]  # Set correct panel ID in this trial
                        if CorrectPanelID == PreCorrectPanelID: # If previous correct panel and current sample panel positions are same, switch them
                            CorrectPanelID = SamplePanelID
                            SamplePanelID = PreCorrectPanelID

                    TrialHistory[CurrTrialNum][0] = PanelPatternID
                    print('PanelPatternID: ' + str(PanelPatternID))

                if TaskType == 'Pre':
                    SamplePanelID = int(random.random() * 10)

                ShowPanel(SamplePanelID)
                if DoneCorrectResponse == 1:    # If this is non-correction trial
                    ResponseType = 'SamplePhaseStart'
                    ResponseTypeID = '0'
                if DoneCorrectResponse == 0:    # If this is correction trial
                    ResponseType = 'SamplePhaseStart(Correction)'
                    ResponseTypeID = '10'
                Writer_TouchEventTxt.write(str(CurrTrialNum+1) + '\t'+ResponseType+'\t' + str(SamplePanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                Writer_TouchEventCsv.write(str(CurrTrialNum+1) + ','+ResponseTypeID+',' + str(SamplePanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                Timer_Start(0)  # Start the latency timer
                Phase2 = 1

            if Phase2 == 1:   # SAMPLE panel presentation phase
                TouchedPanelID = DetectRoiNosepoke() # Check which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID == SamplePanelID: # If mouse touches SAMPLE panel
                    TrialHistory[CurrTrialNum][1] = (TimeNow.day * 60 * 60 * 24) + (TimeNow.hour * 60 * 60) + (TimeNow.minute * 60) + TimeNow.second
                    NowDrinking = 0
                    if TaskType == 'Pre':
                        DoneCorrectResponse = 1
                        CorrectNum[0]+=1
                        #TotalCorrectNum += 1
                        SamplePanelNum[SamplePanelID] += 1

                        ResultStringA = 'SampleTouchNum:' + str(CorrectNum[0])
                        mOngoingResultVar.set(ResultStringA)
                        OutResultStringA = ResultStringA
                    if DoneCorrectResponse == 1:    # If this is non-correction trial
                        if SampleRewardList[CurrTrialNum]==1:
                            ResponseType = 'SampleTouch(Reward)'
                            ResponseTypeID = '1'
                        if SampleRewardList[CurrTrialNum] == 0:
                            ResponseType = 'SampleTouch(NoReward)'
                            ResponseTypeID = '15'
                    if DoneCorrectResponse == 0:    # If this is correction trial
                        if SampleRewardList[CurrTrialNum] == 1:
                            ResponseType = 'SampleTouch(Correction,Reward)'
                            ResponseTypeID = '11'
                        if SampleRewardList[CurrTrialNum] == 0:
                            ResponseType = 'SampleTouch(Correction,NoReward)'
                            ResponseTypeID = '16'
                    Writer_TouchEventTxt.write(str(CurrTrialNum+1) + '\t'+ResponseType+'\t' +str(SamplePanelID)+'\t'+ str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the text file
                    Writer_TouchEventCsv.write(str(CurrTrialNum+1) + ','+ResponseTypeID+',' +str(SamplePanelID)+','+ str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the csv file
                    HidePanel(SamplePanelID)
                    Timer_End(0)
                    Phase2 = 2  # Go to reward
                    if WaterCueType == 'Normal':
                        DigitalOutOn(10)
                    if WaterCueType == 'Blink':
                        DigitalOutBlinkOn(10)
                    ServoPosInside(3)
                    Timer_Start(1)

                if Timer_GetSec(5) >= TimeLimit * 60:   # If time limit is exceeded
                    TaskDur = Timer_GetSec(5)
                    Timer_End(5)
                    Phase2 = 12

            if Phase2 == 2: # Sample reward phase
                if DetectRoiNosepoke() == 19 and NowDrinking == 0:    # If the mouse initiates nose poke
                    NowDrinking = 1
                    Timer_Start(0)  # Start lick timer
                if NowDrinking == 1:
                    if Timer_GetSec(0) > SampleLickDur or SampleRewardList[CurrTrialNum]==0:   # If lick time exceeds the designated time
                        Timer_End(0) # End lick timer
                        ServoPosMiddle(3)    # Move water nozzle to the intermediate position
                        DigitalOutOff(10)
                        NowDrinking = 0
                        Timer_Start(0)  # Start ITI timer
                        if TaskType == 'Pre':
                            Phase2 = 11  # Go to ITI
                        if TaskType == 'TUNL' or TaskType == 'TUNL(L)' or TaskType == 'TUNL(S)':
                            Phase2 = 3 # Go to ITI

            if Phase2 == 3: # Delay phase
                if Timer_GetSec(1) >= DelayDur:
                    ShowPanel(SamplePanelID)
                    ShowPanel(CorrectPanelID)
                    Phase2=4    # Go to Choice phase

            if Phase2 == 4: # Choice phase
                TouchedPanelID = DetectRoiNosepoke()  # Check which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID == CorrectPanelID:    # If mouse touches correct panel
                    NowDrinking = 0
                    if WithinTrialCorrection == 0:
                        TrialHistory[CurrTrialNum][2] = (TimeNow.day * 60 * 60 * 24) + (TimeNow.hour * 60 * 60) + (TimeNow.minute * 60) + TimeNow.second
                        TrialHistory[CurrTrialNum][3] = 1
                        TrialHistory[CurrTrialNum][4] = SeparateDistance
                        TrialNum[SeparateDistance] += 1
                        CorrectNum[SeparateDistance] += 1  # Increase the number of correct respons
                        TotalCorrectNum += 1
                        CorrectRate[SeparateDistance] = round(CorrectNum[SeparateDistance] * 100.0 / TrialNum[SeparateDistance], 2)

                        if DoneCorrectResponse == 1:    # If this is non-correction trial
                            ResponseType = 'CorrectTouch'
                            ResponseTypeID = '2'
                        if DoneCorrectResponse == 0:    # If this is correction trial
                            ResponseType = 'CorrectTouch(NextTrialCorrection)'
                            ResponseTypeID = '12'
                        DoneCorrectResponse = 1
                    if WithinTrialCorrection == 1:
                        ResponseType = 'CorrectTouch(WithinTrialCorrection)'
                        ResponseTypeID = '17'

                    Writer_TouchEventTxt.write(str(CurrTrialNum+1) + '\t'+ResponseType+'\t' + str(TouchedPanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\t" + str(PanelPatternID) + "\t" + str(SeparateDistance) + "\n")  # Write the response on the text file
                    Writer_TouchEventCsv.write(str(CurrTrialNum+1) + ','+ResponseTypeID+',' + str(TouchedPanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "," + str(SeparateDistance) + "\n")  # Write the response on the csv file
                    HidePanel(SamplePanelID)
                    HidePanel(CorrectPanelID)
                    Timer_End(0)
                    if WaterCueType == 'Normal':
                        DigitalOutOn(10)
                    if WaterCueType == 'Blink':
                        DigitalOutBlinkOn(10)
                    ServoPosInside(3)
                    RoofLightOff()  # Turn off roof light
                    Phase2 = 8 # Go to score update phase

                if TouchedPanelID == SamplePanelID and WithinTrialCorrection == 0:   # If mouse touches wrong previously touched panel
                    NowDrinking = 0
                    TrialHistory[CurrTrialNum][2] = (TimeNow.day * 60 * 60 * 24) + (TimeNow.hour * 60 * 60) + (TimeNow.minute * 60) + TimeNow.second
                    TrialHistory[CurrTrialNum][3] = 0
                    TrialHistory[CurrTrialNum][4] = SeparateDistance
                    TrialNum[SeparateDistance] += 1
                    IncorrectNum[SeparateDistance] += 1  # Increase the number of correct response
                    TotalIncorrectNum += 1
                    CorrectRate[SeparateDistance] = round(CorrectNum[SeparateDistance] * 100.0 / TrialNum[SeparateDistance], 2)

                    if DoneCorrectResponse == 1:    # If this is non-correction trial
                        ResponseType = 'IncorrectTouch'
                        ResponseTypeID = '3'
                    if DoneCorrectResponse == 0:    # If this is correction trial
                        ResponseType = 'IncorrectTouch(Correction)'
                        ResponseTypeID = '13'
                    DoneCorrectResponse = 0
                    if CorrectionTrial == "WithinTrial":
                        WithinTrialCorrection = 1
                    Writer_TouchEventTxt.write(str(CurrTrialNum + 1) + '\t'+ResponseType+'\t' + str(TouchedPanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\t" + str(PanelPatternID) + "\t" + str(SeparateDistance) + "\n")  # Write the response on the text file
                    Writer_TouchEventCsv.write(str(CurrTrialNum + 1) + ','+ResponseTypeID+',' + str(TouchedPanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "," + str(SeparateDistance) + "\n")  # Write the response on the csv file

                    if PunishWithLight == 'ON':
                        RoofLightOn()  # Turn on roof light
                    ServoPosOutside(3)
                    if WithinTrialCorrection == 0:  # If within trial correction is turned off
                        Timer_End(0)
                        HidePanel(SamplePanelID)
                        HidePanel(CorrectPanelID)
                        Phase2 = 8  # Go to score update phase
                        Timer_Start(0)

                if Timer_GetSec(5) >= TimeLimit * 60:  # If time limit is exceeded
                    TaskDur = Timer_GetSec(5)
                    Timer_End(5)
                    Phase2 = 12

            if Phase2 == 8:
                PannelPatternNum[PanelPatternID] += 1
                # Caliculate valid score
                ValidCorrectNum = [0 for i in range(2)]  # Correct touch num which have done within the designated delay
                ValidIncorrectNum = [0 for i in range(2)]
                ValidTouchNum = [0 for i in range(2)]
                for i in range(CurrTrialNum+1):  # Loop for trials
                    if TrialHistory[i][2] == -1:  # If this trial is not completed
                        break
                    if TrialHistory[i][2] != -1:  # If this trial is completed
                        ActualDelay = TrialHistory[i][2] - TrialHistory[i][1]
                        if ActualDelay <= AllowedDelay:
                            TempDistance = int(TrialHistory[i][4])
                            ValidTouchNum[TempDistance] += 1
                            if TrialHistory[i][3] == 1:
                                ValidCorrectNum[TempDistance] += 1
                            if TrialHistory[i][3] == 0:
                                ValidIncorrectNum[TempDistance] += 1

                if ValidTouchNum[1] > 0:
                    ValidCorrectRate[1] = round(ValidCorrectNum[1] / ValidTouchNum[1] * 100, 1)
                    ValidResultStringA = '  /  ValidCorrect:' + str(ValidCorrectNum[1]) + '  ValidWrong:' + str(ValidIncorrectNum[1]) + '  ValidTotalNum:' + str(ValidTouchNum[1]) + '  ValidCorrect:' + str(ValidCorrectRate[1]) + '%'
                if ValidTouchNum[0] > 0:
                    ValidCorrectRate[0] = round(ValidCorrectNum[0] / ValidTouchNum[0] * 100, 1)
                    ValidResultStringB = '  /  ValidCorrect:' + str(ValidCorrectNum[0]) + '  ValidWrong:' + str(ValidIncorrectNum[0]) + '  ValidTotalNum:' + str(ValidTouchNum[0]) + '  ValidCorrect:' + str(ValidCorrectRate[0]) + '%'
                    #ValidString[i2] = '  /  ValidCorrect:' + str(ValidCorrectNum) + '  ValidWrong:' + str(ValidIncorrectNum) + '  ValidTotalNum:' + str(ValidTouchNum) + '  ValidCorrect:' + str(ValidCorrectRate) + '%'
                if TrialNum[1] > 0:
                    ResultStringA = 'Large sep.: CorrectNum:' + str(CorrectNum[1]) + '  IncorrectNum:' + str(IncorrectNum[1]) + '  TrialNum:' + str(TrialNum[1]) + '  Correct:' + str(CorrectRate[1]) + '%'
                    OutResultStringA = ResultStringA + ValidResultStringA
                if TrialNum[0] > 0:
                    ResultStringB = 'Small sep.: CorrectNum:' + str(CorrectNum[0]) + '  IncorrectNum:' + str(IncorrectNum[0]) + '  TrialNum:' + str(TrialNum[0]) + '  Correct:' + str(CorrectRate[0]) + '%'
                    OutResultStringB = ResultStringB + ValidResultStringB
                mOngoingResultVar.set(ResultStringA+ValidResultStringA+"\n"+ResultStringB+ValidResultStringB)
                if (CorrectionTrial != "WithinTrial" and DoneCorrectResponse == 1) or CorrectionTrial == "WithinTrial":
                    Phase2 = 9
                if CorrectionTrial != "WithinTrial" and DoneCorrectResponse == 0:
                    Phase2 = 10

            if Phase2 == 9:  # Reward phase
                if DetectRoiNosepoke() == 19 and NowDrinking == 0:    # If the mouse initiates nose poke
                    NowDrinking = 1
                    Timer_Start(0)  # Start lick timer
                if NowDrinking == 1:
                    if Timer_GetSec(0) >= ChoiceLickDur:
                        if (CorrectionTrial != "WithinTrial" and DoneCorrectResponse == 1) or CorrectionTrial == "WithinTrial":   # If lick time exceed the designated time
                            Timer_End(0) # End lick timer
                            ServoPosMiddle(3)    # Move water nozzle to the intermediate position
                            DigitalOutOff(10)
                            NowDrinking = 0
                            Timer_Start(0)  # Start ITI timer
                            Phase2 = 11 # Go to ITI

            if Phase2 == 10:   # Punishment phase
                if Timer_GetSec(0) >= PunishDur or WithinTrialCorrection == 1:    # If punishment time is passed
                    RoofLightOff()
                    ServoPosMiddle(3)    # Move water nozzle to the intermediate position
                    Timer_End(0)  # End punishment timer1
                    Timer_Start(0)  # Start ITI timer
                    Phase2 = 11 # Go to ITI

            if Phase2 == 11:   # ITI
                print(Timer_GetSec(0))
                if Timer_GetSec(0) >= Iti:    # If ITI is passed
                    if TotalCorrectNum >= MaxCorrectNum or CurrTrialNum >= MaxTrialNum-1: # If mouse achieved criteria of finishing the task
                        Timer_End(5)
                        ServoPosMiddle(3)
                        DigitalOutOff(10)
                        Timer_Start(0)  # Timer for interval between task and arbitary water supply is started
                        Phase2 = 12  # Go to the AWS
                    else:
                        CurrTrialNum += 1
                        if TaskType == 'TUNL':
                            if (DoneCorrectResponse == 1 and CorrectionTrial == 'NextTrial') or CorrectionTrial == 'WithinTrial' or CorrectionTrial == 'OFF':
                                Trg=0
                                if SeparateDistance==1:
                                    SeparateDistance = 0    # Change distance
                                    Trg=1
                                if SeparateDistance==0 and Trg==0:
                                    SeparateDistance = 1    # Change distance
                                if SeparateDistance==0:
                                    print('Separation is switched to small')
                                if SeparateDistance==1:
                                    print('Separation is switched to large')
                        WithinTrialCorrection = 0
                        Phase2 = 0  # Go to the next trial

            if Phase2==12:  # End session
                for i in range(10):
                    HidePanel(i)
                if TotalCorrectNum < MaxCorrectNum and AwsOn == 'ON':  # If mouse didn't achieved the max correct response
                    Timer_Start(0)
                    Phase2 = 13
                if TotalCorrectNum == MaxCorrectNum or AwsOn == 'OFF':  # If mouse achieved the max correct response
                    Phase2 = -1

            if Phase2==13:   # Wait until arbitary water suuply is started
                if Timer_GetSec(0) >= 20:   # If the interval is past 20
                    Timer_End(0)
                    ArbitaryWaterSupplyDur=(MaxCorrectNum*ChoiceLickDur - TotalCorrectNum*ChoiceLickDur)  * 1000    # Caliculate duration of complement water supply
                    if WaterCueType == 'Normal':
                        StartArbitaryWaterSupply(3,10,0,ArbitaryWaterSupplyDur) # Start complement water supply
                    if WaterCueType == 'Blink':
                        StartArbitaryWaterSupply(3,10,1,ArbitaryWaterSupplyDur) # Start complement water supply
                    print("AWSstart")
                    Phase2=14
            if Phase2==14:
                if GetArbitaryWaterSupplyStat()==1: # If complement water supply is finished
                    Phase2 = -1

            if Phase2 == -1 or GetEndTaskNowButtonStat() == 1:  # Task finish phase
                LightCycleControlOn()
                ServoPosMiddle(3)
                DeleteAllPanel()
                InfraredLightOff()
                if GetRecordingStat() == 1:
                    SetEndRecordingTimer(60)

                if (TaskType == 'Pre' and TotalCorrectNum > 0) or (TaskType == 'TUNL' and TrialNum[1] > 0) or (TaskType == 'TUNL(L)' and TrialNum[1] > 0) or (TaskType == 'TUNL(S)' and TrialNum[1] > 0):
                    Writer_TouchEventTxt.write(OutResultStringA+'\n')   #Summary of results
                if (TaskType == 'TUNL' and TrialNum[0] > 0) or (TaskType == 'TUNL(L)' and TrialNum[0] > 0) or (TaskType == 'TUNL(S)' and TrialNum[0] > 0):
                    Writer_TouchEventTxt.write(OutResultStringB+'\n')   #Summary of results

                Writer_TouchEventTxt.write('SessionStartTime: ' + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()) + "\n")
                Writer_TouchEventTxt.write('SessionEndTime: ' + str(TimeNow.month) + '/' + str(TimeNow.day) + ' ' + str(TimeNow.hour) + ':' + str(TimeNow.minute) + ':' + str(TimeNow.second + (TimeNow.microsecond // 1000) / 1000) + "\n")
                Writer_TouchEventTxt.write('TaskDuration(sec): ' + str(TaskDur) + "\n")
                if TaskType == 'TUNL' or TaskType == 'TUNL(L)' or TaskType == 'TUNL(S)':
                    Writer_TouchEventTxt.write('Delay(sec): ' + str(DelayDur) + "\n")
                Writer_TouchEventTxt.write('MaxCorrectNum: '+str(MaxCorrectNum)+"\n")
                Writer_TouchEventTxt.write('MaxTrialNum: ' + str(MaxTrialNum) + "\n")
                Writer_TouchEventTxt.write('TimeLimit(min): ' + str(TimeLimit) + "\n")
                if TaskType == 'TUNL'or TaskType == 'TUNL(L)' or TaskType == 'TUNL(S)':
                    Writer_TouchEventTxt.write('PunishDur(sec): ' + str(PunishDur) + "\n")
                Writer_TouchEventTxt.write('SampleRewardRate(%): ' + str(SampleRewardRate) + "\n")
                Writer_TouchEventTxt.write('SampleLickDur(sec): ' + str(SampleLickDur) + "\n")
                Writer_TouchEventTxt.write('ChoiceLickDur(sec): ' + str(ChoiceLickDur) + "\n")
                Writer_TouchEventTxt.write('Iti(sec): ' + str(Iti) + "\n")
                if TaskType == 'TUNL'or TaskType == 'TUNL(L)' or TaskType == 'TUNL(S)':
                    Writer_TouchEventTxt.write('ValidDelay(%): ' + str(DelayAllowFactor) + "\n")
                Writer_TouchEventTxt.write('Seed: ' + str(Seed) + "\n")
                Writer_TouchEventTxt.write('DayTh: ' + str(DayTh) + "\n")
                Writer_TouchEventTxt.write('NextTask: ' + str(NextTask) + "\n")
                Writer_TouchEventTxt.write('TaskType: ' + str(TaskType) + "\n")
                Writer_TouchEventTxt.write('CorrectionTrial: ' + str(CorrectionTrial) + "\n")
                Writer_TouchEventTxt.write('WaterCueType: ' + str(WaterCueType) + "\n")
                Writer_TouchEventTxt.write('PunishLight: ' + str(PunishWithLight) + "\n")
                Writer_TouchEventTxt.write('RecordFPS: ' + str(GetRecordFps()) + "\n")
                Writer_TouchEventTxt.write('AWS: ' + AwsOn + "\n")
                Writer_TouchEventTxt.write('AWS_Latency: ' + str(AWS_Latency) + "\n")

                if TaskType == 'Pre':
                    for i in range(10):
                        Writer_TouchEventTxt.write('Shown sample panel ' + str(i) +' num : '+ str(SamplePanelNum[i]) + "\n")
                if TaskType == 'TUNL' or TaskType == 'TUNL(L)' or TaskType == 'TUNL(S)':
                    for i in range(MaxPanelPattern):
                        Writer_TouchEventTxt.write('Pannel pattern ' + str(i) +': '+ str(PannelPatternNum[i]) + "\n")
                Writer_TouchEventTxt.write(GetRoiSensitivity() + "\n")
                Writer_TouchEventTxt.write(GetServoAngle() + "\n")

                Writer_TouchEventTxt.close()
                Writer_TouchEventCsv.close()
                EndLickRecording()

                SendMail(DeviceNameVar.get() + ' finished task '+str(GetTaskID())+'.'+ResultStringA+';  '+ResultStringB+';  Dur:' + str(round(Timer_GetSec(5) / 60,1)) + ' min', 'Task is finished.')

                if IsHousingAnalysis == 1:  # If it is housing analysis
                    ElapsedDay+=1
                    if ElapsedDay >= DayTh:  # If the score exceed the criteria to switch the next task
                        SwitchTask(NextTask)  # Onset task switch trigger
                        print("Task is switched to task#" + str(NextTask) + "  " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

                if IsHousingAnalysis == 0:
                    RoofLightOn()

                Phase = 1  # Go back to the task-waiting phase
                Phase2 = 0
                Phase2_Init = 0
                ShowTouchCursor()
            SetDispVariable(0, 'Phase2', str(Phase2))  # Display "Phase2" value on the main window
    return

def Task11():   # Go-NoGo task
    global Phase
    Phase0_Init=0
    Phase1_Init = 0
    Phase2_Init = 0
    while EndFlag == 0:
        OperantHouseUpdate()

        if GetBackButtonStat()==1:    # If "Back" button is clicked
            break   # Back to the task select phase
        if Phase == 0:  # Parameter inputs
            if Phase0_Init == 0:
                # Make GUI for the setting of the parameters for this task
                RemoveMainRightWidget() # Remove task buttons
                PutStartBackButton()    # Put start/back buttons

                ColumnWidth = 14
                Row = 0  # Begin a new line
                Column = 0
                mMaxCorrectNum = ttk.Label(MainWindowRightFrame, text='MaxCorrectNum', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                MaxCorrectNumVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iMaxCorrectNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxCorrectNumVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mTimeLimit = ttk.Label(MainWindowRightFrame, text='TimeLimit(min)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                TimeLimitVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iTimeLimit = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mPresentDur = ttk.Label(MainWindowRightFrame, text='PresentDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                PresentDurVar = DoubleVar(MainWindowRoot)
                iPresentDur = ttk.Entry(MainWindowRightFrame, textvariable=PresentDurVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mPunishDur = ttk.Label(MainWindowRightFrame, text='PunishDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                PunishDurVar = DoubleVar(MainWindowRoot)
                iPunishDur = ttk.Entry(MainWindowRightFrame, textvariable=PunishDurVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mIti = ttk.Label(MainWindowRightFrame, text='ITI(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                ItiVar = DoubleVar(MainWindowRoot)
                iIti = ttk.Entry(MainWindowRightFrame, textvariable=ItiVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mLickDur = ttk.Label(MainWindowRightFrame, text='LickDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                LickDurVar = DoubleVar(MainWindowRoot)
                iLickDur = ttk.Entry(MainWindowRightFrame, textvariable=LickDurVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field

                Row += 2  # Begin a new line
                Column = 0

                mNextTask = ttk.Label(MainWindowRightFrame, text='NextTask#', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                NextTaskVar = IntVar(MainWindowRoot)
                iNextTask = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mNextTaskTh = ttk.Label(MainWindowRightFrame, text='NextTaskTh(Correct%)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                NextTaskThVar = DoubleVar(MainWindowRoot)
                iNextTaskTh = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskThVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mTaskType = ttk.Label(MainWindowRightFrame, text='TaskType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                TaskTypeVar = StringVar(MainWindowRightFrame)  # Declare variable receiving value from the entry field
                tTaskType = OptionMenu(MainWindowRightFrame, TaskTypeVar, "Go", "NoGo").grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mPunishLight = ttk.Label(MainWindowRightFrame, text='PunishLight', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                PunishLightVar = StringVar(MainWindowRightFrame)
                tPunishLight = OptionMenu(MainWindowRightFrame, PunishLightVar, "ON", "OFF").grid(row=Row+1, column=Column)  # Put dropdown list
                Column += 1  # Shift column
                mPanelType = ttk.Label(MainWindowRightFrame, text='PanelType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                PanelTypeVar = StringVar(MainWindowRightFrame)
                tPanelType = OptionMenu(MainWindowRightFrame, PanelTypeVar, "Normal", "Blink", "Textured").grid(row=Row+1, column=Column)  # Put dropdown list
                Column += 1  # Shift column
                mWaterCueType = ttk.Label(MainWindowRightFrame, text='WaterCueType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                WaterCueTypeVar = StringVar(MainWindowRightFrame)
                tWaterCueType = OptionMenu(MainWindowRightFrame, WaterCueTypeVar, "Normal", "Blink").grid(row=Row+1, column=Column)  # Put dropdown list

                Str = "ParametersForTask" + str(GetTaskID())
                if os.path.exists(Str + '/MaxCorrectNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxCorrectNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxCorrectNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxCorrectNumVar.set(80)  # Default value
                if os.path.exists(Str + '/TimeLimit.dat') == True:  # If save file exists
                    with open(Str + '/TimeLimit.dat', 'rb') as PickleInst[GetTaskID()]:
                        TimeLimitVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    TimeLimitVar.set(360)  # Default value
                if os.path.exists(Str + '/PresentDur.dat') == True:  # If save file exists
                    with open(Str + '/PresentDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        PresentDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PresentDurVar.set(5)  # Default value

                if os.path.exists(Str + '/PunishDur.dat') == True:  # If save file exists
                    with open(Str + '/PunishDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishDurVar.set(10)  # Default value

                if os.path.exists(Str + '/Iti.dat') == True:  # If save file exists
                    with open(Str + '/Iti.dat', 'rb') as PickleInst[GetTaskID()]:
                        ItiVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    ItiVar.set(5)  # Default value
                if os.path.exists(Str + '/LickDur.dat') == True:  # If save file exists
                    with open(Str + '/LickDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        LickDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    LickDurVar.set(2)  # Default value
                if os.path.exists(Str + '/NextTaskTh.dat') == True:  # If save file exists
                    with open(Str + '/NextTaskTh.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskThVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskThVar.set(999)  # Default value
                if os.path.exists(Str + '/NextTask.dat') == True:  # If save file exists
                    with open(Str + '/NextTask.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskVar.set(11)  # Default value
                if os.path.exists(Str + '/TaskType.dat') == True:  # If save file exists
                    with open(Str + '/TaskType.dat', 'rb') as PickleInst[GetTaskID()]:
                        TaskTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    TaskTypeVar.set('Go')  # Default value
                if os.path.exists(Str + '/PunishLight.dat') == True:  # If save file exists
                    with open(Str + '/PunishLight.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishLightVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishLightVar.set('ON')  # Default value

                if os.path.exists(Str + '/PanelType.dat') == True:  # If save file exists
                    with open(Str + '/PanelType.dat', 'rb') as PickleInst[GetTaskID()]:
                        PanelTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PanelTypeVar.set('Normal')  # Default value

                if os.path.exists(Str + '/WaterCueType.dat') == True:  # If save file exists
                    with open(Str + '/WaterCueType.dat', 'rb') as PickleInst[GetTaskID()]:
                        WaterCueTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    WaterCueTypeVar.set('Normal')  # Default value

                RemoveAllRoiGui()
                PutRoiGui(0, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(19, 0, 0, 1)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)

                RemoveAllDigitalOutGui()
                PutDigitalOutGui(10)
                PutDigitalOutGui(12)
                PutDigitalOutGui(13)

                RemoveAllServoGui()
                PutServoGui(3)

                Phase0_Init = 1

        if GetSaveTrgStat() == 1:    # If save trigger is on
            # Parameters of each task are saved into different folder
            Str="ParametersForTask"+str(GetTaskID())   # Path to the folder for saving of parameters
            if os.path.exists(Str) == False:    # If folder for saving parameters is not exist
                os.mkdir(Str)   # Make folder for saving
            with open(Str+'/MaxCorrectNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxCorrectNumVar.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/TimeLimit.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TimeLimitVar.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/PresentDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PresentDurVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/PunishDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishDurVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/Iti.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(ItiVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/LickDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(LickDurVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/NextTaskTh.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskThVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str + '/NextTask.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str+'/TaskType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TaskTypeVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/PunishLight.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishLightVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/PanelType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PanelTypeVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/WaterCueType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(WaterCueTypeVar.get(), PickleInst[GetTaskID()])     # Save

        if Phase == 1:  # Wait for starting of task
            if Phase1_Init == 0:
                PutPreTaskButton()
                mStatusVar = StringVar(MainWindowRoot)
                mStatus = ttk.Label(MainWindowRightFrame, textvariable=mStatusVar)
                mStatus.place(x=10, y=0)
                mOngoingResultVar = StringVar(MainWindowRoot)
                Phase1_Init = 1
            mStatusVar.set('Go/NoGo task (' + str(GetTaskID()) + ')    Waiting...')
            if IsStartTime() == 1:
                StartNow()

        if Phase == 2:  # During task
            if Phase2_Init == 0: # Initialization of the task
                PutEndTaskNowButton()
                mStatusVar.set('Go/NoGo task (' + str(GetTaskID()) + ')    Start time ' + str(TaskStartedMonth) + '/' + str(TaskStartedDay) + ' ' + str(TaskStartedHour) + ':' + str(TaskStartedMinute) + '    Running')
                mOngoingResult = ttk.Label(MainWindowRightFrame, textvariable=mOngoingResultVar)
                mOngoingResult.place(x=10, y=18)

                # Convert StringVars of parameters into integer or normal string to use in the following
                MaxCorrectNum=int(MaxCorrectNumVar.get())
                TimeLimit = float(TimeLimitVar.get())
                PresentDur = float(PresentDurVar.get())
                PunishDur = float(PunishDurVar.get())
                Iti = float(ItiVar.get())
                LickDur = float(LickDurVar.get())
                NextTaskTh = float(NextTaskThVar.get())
                NextTask = int(NextTaskVar.get())
                TaskType = TaskTypeVar.get()
                PunishLight = PunishLightVar.get()
                PanelType = PanelTypeVar.get()
                WaterCueType = WaterCueTypeVar.get()


                # Declar local variables for this task
                CorrectNum=0
                IncorrectNum=0
                TouchNum=0
                CorrectRate=0
                Writer_TouchEventTxt = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.txt", 'w')  # Initialize the text exporter
                Writer_TouchEventCsv = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.csv", 'w')  # Initialize the text exporter
                StartLickRecording()
                ArbitaryWaterSupplyDur=0
                TaskDur = 0

                LightCycleControlOff()
                DoneCorrectResponse = 1
                RoofLightOff()
                InfraredLightOn()
                if WaterCueType == 'Normal':
                    DigitalOutOn(10)
                if WaterCueType == 'Blink':
                    DigitalOutBlinkOn(10)
                ServoPosInside(3)
                NowDrinking = 0
                NowPunishing = 0
                AutoWaterSupplyNum = 0
                AWS_Latency=0
                StartRecording()    # Start camera capturing and sending of TTL

                if PanelType == 'Normal':
                    CreateNormalPanel(0)
                if PanelType == 'Blink':
                    CreateBlinkPanel(0)
                if PanelType == 'Textured':
                    CreateTexturedPanel(0,0)

                Writer_TouchEventTxt.write('TrialNum\tResult\t\t\tyyyy/mm/dd\th:m\ts\n')  # Write item name
                TrialNum=0

                Timer_Start(5)  # Task time limit timer start
                Phase2 = 2
                Phase2_Init = 1
                print("Task #" + str(GetTaskID()) + " is started at " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(
                    GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

            if Phase2 == 0:   # Initiation of new trial
                TaskDur = Timer_GetSec(5)
                DoneCorrectResponse=0
                ShowPanel(0)
                TrialNum += 1
                Timer_Start(0)  # Start the latency timer
                Phase2 += 1
            if Phase2 == 1:   # Panel presentation
                TouchedPanelID = DetectRoiNosepoke()  # Examine which panel is touched (return panel ID. If none of the panels touched, return -1)
                if (TaskType == 'Go' and TouchedPanelID!=-1) or (TaskType=='NoGo' and Timer_GetSec(0) >= PresentDur): # If mouse responses correctly
                    #ShowTouchSymbol(30)
                    DoneCorrectResponse = 1
                    ServoPosInside(3)    # Move water nozzle to the inside position
                    if WaterCueType == 'Normal':
                        DigitalOutOn(10)
                    if WaterCueType == 'Blink':
                        DigitalOutBlinkOn(10)
                    NowDrinking = 0
                    CorrectNum += 1      # Increase the number of correct response
                    TouchNum+=1
                    if TaskType == 'Go':
                        mOngoingResultVar.set(
                            'CorrectNum:' + str(CorrectNum) + '  IncorrectNum:' + str(IncorrectNum) + '  TotalNum:' + str(TouchNum) + '  Correct:' + str(CorrectNum * 100.0 / TouchNum) + '%')
                        Writer_TouchEventTxt.write(str(TrialNum)+'\tPanelTouched(Correct)\t'+ str(TimeNow.year)+"/"+str(TimeNow.month)+"/"+str(TimeNow.day)+"\t"+str(TimeNow.hour)+":"+str(TimeNow.minute)+"\t"+str(TimeNow.second)+"."+str(TimeNow.microsecond//1000)+"\n") # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',1,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000)+"\n")  # Write the response on the csv file
                    if TaskType == 'NoGo':
                        mOngoingResultVar.set('CorrectNum:' + str(CorrectNum) + '  IncorrectNum:' + str(IncorrectNum) + '  TotalNum:' + str(TouchNum) + '  Correct:' + str(
                            CorrectNum * 100.0 / TouchNum) + '%')
                        Writer_TouchEventTxt.write(str(TrialNum)+'\tPanelIgnored(Correct)\t'+str(TimeNow.year)+"/"+str(TimeNow.month)+"/"+str(TimeNow.day)+"\t"+str(TimeNow.hour)+":"+str(TimeNow.minute)+"\t"+str(TimeNow.second)+"."+str(TimeNow.microsecond//1000)+"\n") # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',1,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000)+"\n")  # Write the response on the csv file
                    HidePanel(0)
                    Timer_End(0)
                    if WaterCueType == 'Normal':
                        DigitalOutOn(10)
                    if WaterCueType == 'Blink':
                        DigitalOutBlinkOn(10)
                    Phase2 = 2  # Start reward phase
                if (TaskType == 'NoGo' and TouchedPanelID!=-1) or (TaskType =='Go' and Timer_GetSec(0) >= PresentDur):  # If mouse responses incorrectly
                    NowPunishing = 1
                    ServoPosOutside(3)
                    if PunishLight =='ON':
                        RoofLightOn()   # Turn on roof light
                    IncorrectNum += 1
                    TouchNum += 1
                    if TaskType == 'Go':
                        mOngoingResultVar.set('CorrectNum:' + str(CorrectNum) + '  IncorrectNum:' + str(IncorrectNum) + '  TotalNum:' + str(TouchNum) + '  Correct:' + str(
                            CorrectNum * 100.0 / TouchNum) + '%')
                        Writer_TouchEventTxt.write(str(TrialNum) + '\tPanelIgnored(Wrong)\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000)+"\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',0,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000)+"\n")  # Write the response on the csv file
                    if TaskType == 'NoGo':
                        mOngoingResultVar.set('CorrectNum:' + str(CorrectNum) + '  IncorrectNum:' + str(IncorrectNum) + '  TotalNum:' + str(TouchNum) + '  Correct:' + str(
                            CorrectNum * 100.0 / TouchNum) + '%')
                        Writer_TouchEventTxt.write(str(TrialNum) + '\tPanelTouched(Wrong)\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000)+ "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',0,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000)+"\n")  # Write the response on the csv file
                    HidePanel(0)
                    Timer_End(0)    # End timer1
                    Timer_Start(0)  # Start punish timer
                    Phase2 = 5 # Start punishment phase
                if Timer_GetSec(5) >= TimeLimit * 60:   # If time limit is exceeded
                    TaskDur = Timer_GetSec(5)
                    Timer_End(5)
                    Phase2 = 6
            if Phase2 == 2:  # Reward phase
                if DetectRoiNosepoke() == 19 and NowDrinking == 0:    # If the mouse initiates nose poke
                    NowDrinking = 1
                    Timer_Start(0)  # Start lick timer
                if NowDrinking == 1:
                    if DoneCorrectResponse == 1 and Timer_GetSec(0) >= LickDur:   # If lick time exceed the designated time
                        Timer_End(0) # End lick timer
                        ServoPosMiddle(3)    # Move water nozzle to the intermediate position
                        DigitalOutOff(10)
                        NowDrinking = 0
                        Timer_Start(0)  # Start ITI timer
                        Phase2 = 3
            if Phase2 == 3:   # ITI
                if Timer_GetSec(0) >= Iti:  # If ITI is passed
                    Timer_End(0)
                    Phase2 = 0  # Go to the next trial
                if CorrectNum >= MaxCorrectNum:
                    Timer_End(5)
                    Phase2=6 # Go to the task finish phase
            if Phase2 == 5:   # Punishment phase
                if Timer_GetSec(0) >= PunishDur:    # If punishment time is passed
                    RoofLightOff()
                    NowPunishing = 0
                    ServoPosMiddle(3)    # Move water nozzle to the intermediate position
                    Timer_End(0)  # End punishment timer1
                    Timer_Start(0)  # Start ITI timer
                    Phase2 = 3
            if Phase2 == 6:
                HidePanel(0)
                if CorrectNum < MaxCorrectNum:    # If mouse didn't achieved the max correct response
                    Timer_Start(0)  # Timer for interval between task and arbitary water supply is started
                    Phase2 = 7
                if CorrectNum == MaxCorrectNum:    # If mouse achieved the max correct response
                    Phase2 = -1
            if Phase2 == 7:  # Wait until arbitary water suuply is started
                if Timer_GetSec(0) >= AWS_Latency:  # If the interval is past 60 20
                    Timer_End(0)
                    ArbitaryWaterSupplyDur = (MaxCorrectNum - CorrectNum) * LickDur * 1000  # Caliculate duration of complement water supply
                    if WaterCueType == 'Normal':
                        StartArbitaryWaterSupply(3,10,0,ArbitaryWaterSupplyDur) # Start complement water supply
                    if WaterCueType == 'Blink':
                        StartArbitaryWaterSupply(3,10,1,ArbitaryWaterSupplyDur) # Start complement water supply
                    #print("AWSstart")
                    Phase2 = 8
            if Phase2 == 8:
                if GetArbitaryWaterSupplyStat() == 1:  # If complement water supply is finished
                    Phase2 = -1

            if Phase2 == -1 or GetEndTaskNowButtonStat() == 1:  # Task finish phase   #
                LightCycleControlOn()
                ServoPosMiddle(3)
                #if Panel!=null:
                DeleteAllPanel()
                InfraredLightOff()
                NowPunishing = 0
                if GetRecordingStat() == 1:
                    SetEndRecordingTimer(60)
                if CorrectNum > 0 or IncorrectNum > 0:
                    CorrectRate = int(CorrectNum * 100.0 / (CorrectNum + IncorrectNum))
                    Writer_TouchEventTxt.write('TotalNum:'+str(CorrectNum+IncorrectNum)+'  Correct num:'+str(CorrectNum)+'  Incorrect num:'+str(IncorrectNum)+'  Correct rate'+str(CorrectRate)+'%'+"\n")   #結果テキストの一番最後に成績のまとめを記入
                Writer_TouchEventTxt.write('SessionStartTime: ' + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()) + "\n")
                Writer_TouchEventTxt.write('SessionEndTime: ' + str(TimeNow.month) + '/' + str(TimeNow.day) + ' ' + str(TimeNow.hour) + ':' + str(TimeNow.minute) + ':' + str(TimeNow.second + (TimeNow.microsecond // 1000) / 1000) + "\n")
                Writer_TouchEventTxt.write('TaskDuration(sec): ' + str(TaskDur) + "\n")
                Writer_TouchEventTxt.write('MaxCorrectNum: '+str(MaxCorrectNum)+"\n")
                Writer_TouchEventTxt.write('TimeLimit: ' + str(TimeLimit) + "\n")
                Writer_TouchEventTxt.write('PresentDur: ' + str(PresentDur)+"\n")
                Writer_TouchEventTxt.write('PunishDur: ' + str(PunishDur)+"\n")
                Writer_TouchEventTxt.write('Iti: ' + str(Iti)+"\n")
                Writer_TouchEventTxt.write('LickDur: ' + str(LickDur)+"\n")
                Writer_TouchEventTxt.write('NextTaskTh: ' + str(NextTaskTh)+"\n")
                Writer_TouchEventTxt.write('NextTask: ' + str(NextTask)+"\n")
                Writer_TouchEventTxt.write('TaskType: ' + str(TaskType)+"\n")
                Writer_TouchEventTxt.write('PunishLight: ' + str(PunishLight)+"\n")
                Writer_TouchEventTxt.write('PanelType: ' + str(PanelType)+"\n")
                Writer_TouchEventTxt.write('WaterCueType: ' + str(WaterCueType)+"\n")
                Writer_TouchEventTxt.write('RecordFPS: ' + str(GetRecordFps()) + "\n")
                Writer_TouchEventTxt.write('AWS_Latency: ' + str(AWS_Latency) + "\n")
                Writer_TouchEventTxt.write(GetRoiSensitivity() + "\n")
                Writer_TouchEventTxt.write(GetServoAngle() + "\n")

                Writer_TouchEventTxt.close()
                Writer_TouchEventCsv.close()
                EndLickRecording()
                SendMail(DeviceNameVar.get()+' finished task '+str(GetTaskID())+'. Correct:'+str(CorrectNum)+' Incorrect:'+str(IncorrectNum)+' Dur:'+str(round(Timer_GetSec(5) / 60,1))+' min','The task is finished.')

                if IsHousingAnalysis == 1 and Phase2 == -1:  # If it is housing analysis
                    if CorrectRate >= NextTaskTh:  # If the score exceed the criteria to switch the next task
                        SwitchTask(NextTask)  # Onset task switch trigger
                        print("Task is switched to task#" + str(NextTask) + "  " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))
                if IsHousingAnalysis == 0:
                    RoofLightOn()
                Phase = 1  # Go back to the task-waiting phase
                Phase2 = 0
                Phase2_Init = 0
            SetDispVariable(0, 'Phase2', str(Phase2))  # Display "Phase2" value on the main window
    return

def Task12():   # Habitual behavior task
    global Phase
    Phase0_Init=0
    Phase1_Init = 0
    Phase2_Init = 0
    while EndFlag == 0:
        OperantHouseUpdate()    # House keeping function
        if GetBackButtonStat()==1:    # If "Back" button is clicked
            break   # Back to the task select phase
        if Phase == 0:  # Parameter inputs
            if Phase0_Init == 0:
                # Make GUI for the setting of the parameters for this task
                RemoveMainRightWidget() # Remove task buttons
                PutStartBackButton()    # Put start/back buttons

                ColumnWidth = 14
                Row = 0  # Begin a new line
                Column = 0

                mMaxCorrectNum = ttk.Label(MainWindowRightFrame, text='MaxCorrectNum', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                MaxCorrectNumVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iMaxCorrectNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxCorrectNumVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mTimeLimit = ttk.Label(MainWindowRightFrame, text='TimeLimit(min)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                TimeLimitVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iTimeLimit = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mRandomInterval = ttk.Label(MainWindowRightFrame, text='Random interval(sec)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                RandomIntervalVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iRandomInterval = ttk.Entry(MainWindowRightFrame, textvariable=RandomIntervalVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mRandomRate = ttk.Label(MainWindowRightFrame, text='Random rate(%)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                RandomRateVar = DoubleVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iRandomRate = ttk.Entry(MainWindowRightFrame, textvariable=RandomRateVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mPresentDur = ttk.Label(MainWindowRightFrame, text='PresentDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                PresentDurVar = DoubleVar(MainWindowRoot)
                iPresentDur = ttk.Entry(MainWindowRightFrame, textvariable=PresentDurVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mPunishDur = ttk.Label(MainWindowRightFrame, text='PunishDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                PunishDurVar = DoubleVar(MainWindowRoot)
                iPunishDur = ttk.Entry(MainWindowRightFrame, textvariable=PunishDurVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mIti = ttk.Label(MainWindowRightFrame, text='ITI(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                ItiVar = DoubleVar(MainWindowRoot)
                iIti = ttk.Entry(MainWindowRightFrame, textvariable=ItiVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field

                Row += 2  # Begin a new line
                Column = 0

                mLickDur = ttk.Label(MainWindowRightFrame, text='LickDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                LickDurVar = DoubleVar(MainWindowRoot)
                iLickDur = ttk.Entry(MainWindowRightFrame, textvariable=LickDurVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mNextTask = ttk.Label(MainWindowRightFrame, text='NextTask#', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                NextTaskVar = IntVar(MainWindowRoot)
                iNextTask = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mNextTaskTh = ttk.Label(MainWindowRightFrame, text='NextTaskTh(Correct%)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                NextTaskThVar = DoubleVar(MainWindowRoot)
                iNextTaskTh = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskThVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mTaskType = ttk.Label(MainWindowRightFrame, text='TaskType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                TaskTypeVar = StringVar(MainWindowRightFrame)  # Declare variable receiving value from the entry field
                tTaskType = OptionMenu(MainWindowRightFrame, TaskTypeVar, "Train(RI)","Train(RR)", "Devaluation", "Omission").grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mPunishLight = ttk.Label(MainWindowRightFrame, text='PunishLight', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                PunishLightVar = StringVar(MainWindowRightFrame)
                tPunishLight = OptionMenu(MainWindowRightFrame, PunishLightVar, "ON", "OFF").grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mPanelType = ttk.Label(MainWindowRightFrame, text='PanelType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                PanelTypeVar = StringVar(MainWindowRightFrame)
                tPanelType = OptionMenu(MainWindowRightFrame, PanelTypeVar, "Normal", "Blink", "Textured").grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mWaterCueType = ttk.Label(MainWindowRightFrame, text='WaterCueType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                WaterCueTypeVar = StringVar(MainWindowRightFrame)
                tWaterCueType = OptionMenu(MainWindowRightFrame, WaterCueTypeVar, "Normal", "Blink").grid(row=Row+1, column=Column)  # Place entry field

                Str = "ParametersForTask" + str(GetTaskID())
                if os.path.exists(Str + '/MaxCorrectNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxCorrectNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxCorrectNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxCorrectNumVar.set(80)  # Default value
                if os.path.exists(Str + '/TimeLimit.dat') == True:  # If save file exists
                    with open(Str + '/TimeLimit.dat', 'rb') as PickleInst[GetTaskID()]:
                        TimeLimitVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    TimeLimitVar.set(360)  # Default value
                if os.path.exists(Str + '/RandomInterval.dat') == True:  # If save file exists
                    with open(Str + '/RandomInterval.dat', 'rb') as PickleInst[GetTaskID()]:
                        RandomIntervalVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    RandomIntervalVar.set(30)  # Default value
                if os.path.exists(Str + '/RandomRate.dat') == True:  # If save file exists
                    with open(Str + '/RandomRate.dat', 'rb') as PickleInst[GetTaskID()]:
                        RandomRateVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    RandomRateVar.set(50)  # Default value
                if os.path.exists(Str + '/PresentDur.dat') == True:  # If save file exists
                    with open(Str + '/PresentDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        PresentDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PresentDurVar.set(20)  # Default value

                if os.path.exists(Str + '/PunishDur.dat') == True:  # If save file exists
                    with open(Str + '/PunishDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishDurVar.set(1)  # Default value

                if os.path.exists(Str + '/Iti.dat') == True:  # If save file exists
                    with open(Str + '/Iti.dat', 'rb') as PickleInst[GetTaskID()]:
                        ItiVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    ItiVar.set(1)  # Default value
                if os.path.exists(Str + '/LickDur.dat') == True:  # If save file exists
                    with open(Str + '/LickDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        LickDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    LickDurVar.set(2)  # Default value
                if os.path.exists(Str + '/NextTaskTh.dat') == True:  # If save file exists
                    with open(Str + '/NextTaskTh.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskThVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskThVar.set(999)  # Default value
                if os.path.exists(Str + '/NextTask.dat') == True:  # If save file exists
                    with open(Str + '/NextTask.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskVar.set(12)  # Default value
                if os.path.exists(Str + '/TaskType.dat') == True:  # If save file exists
                    with open(Str + '/TaskType.dat', 'rb') as PickleInst[GetTaskID()]:
                        TaskTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    TaskTypeVar.set('Train(RI)')  # Default value
                if os.path.exists(Str + '/PunishLight.dat') == True:  # If save file exists
                    with open(Str + '/PunishLight.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishLightVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishLightVar.set('Train(RI)')  # Default value

                if os.path.exists(Str + '/PanelType.dat') == True:  # If save file exists
                    with open(Str + '/PanelType.dat', 'rb') as PickleInst[GetTaskID()]:
                        PanelTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PanelTypeVar.set('Normal')  # Default value

                if os.path.exists(Str + '/WaterCueType.dat') == True:  # If save file exists
                    with open(Str + '/WaterCueType.dat', 'rb') as PickleInst[GetTaskID()]:
                        WaterCueTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    WaterCueTypeVar.set('Blink')  # Default value

                RemoveAllRoiGui()
                PutRoiGui(0, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(19, 0, 0, 1)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)

                RemoveAllDigitalOutGui()
                PutDigitalOutGui(10)
                PutDigitalOutGui(12)
                PutDigitalOutGui(13)

                RemoveAllServoGui()
                PutServoGui(3)

                Phase0_Init = 1

        if GetSaveTrgStat() == 1:    # If save trigger is on
            # Parameters of each task are saved into different folder
            Str="ParametersForTask"+str(GetTaskID())   # Path to the folder for saving of parameters
            if os.path.exists(Str) == False:    # If folder for saving parameters is not exist
                os.mkdir(Str)   # Make folder for saving
            with open(Str+'/MaxCorrectNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxCorrectNumVar.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/TimeLimit.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TimeLimitVar.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/RandomInterval.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(RandomIntervalVar.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/RandomRate.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(RandomRateVar.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/PresentDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PresentDurVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/PunishDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishDurVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/Iti.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(ItiVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/LickDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(LickDurVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/NextTaskTh.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskThVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str + '/NextTask.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str+'/TaskType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TaskTypeVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/PunishLight.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishLightVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/PanelType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PanelTypeVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/WaterCueType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(WaterCueTypeVar.get(), PickleInst[GetTaskID()])     # Save

        if Phase == 1:  # Wait for starting of task
            if Phase1_Init == 0:
                PutPreTaskButton()
                mStatusVar = StringVar(MainWindowRoot)
                mStatus = ttk.Label(MainWindowRightFrame, textvariable=mStatusVar)
                mStatus.place(x=10, y=0)
                mOngoingResultVar = StringVar(MainWindowRoot)
                Phase1_Init = 1
            mStatusVar.set('Habitual behavior task (' + str(GetTaskID()) + ')    Waiting...')
        if Phase == 2:  # During task
            if Phase2_Init == 0: # Initialization of the task
                PutEndTaskNowButton()
                mStatusVar.set('Habitual behavior task (' + str(GetTaskID()) + ')    Start time ' + str(TaskStartedMonth) + '/' + str(TaskStartedDay) + ' ' + str(TaskStartedHour) + ':' + str(TaskStartedMinute) + '    Running')
                mOngoingResult = ttk.Label(MainWindowRightFrame, textvariable=mOngoingResultVar)
                mOngoingResult.place(x=10, y=18)

                # Convert StringVars of parameters into integer or normal string to use in the following
                MaxCorrectNum=int(MaxCorrectNumVar.get())
                TimeLimit = float(TimeLimitVar.get())
                RandomInterval=float(RandomIntervalVar.get())
                RandomRate = float(RandomRateVar.get())
                PresentDur = float(PresentDurVar.get())
                PunishDur = float(PunishDurVar.get())
                Iti = float(ItiVar.get())
                LickDur = float(LickDurVar.get())
                NextTaskTh = float(NextTaskThVar.get())
                NextTask = int(NextTaskVar.get())
                TaskType = TaskTypeVar.get()
                PunishLight = PunishLightVar.get()
                PanelType = PanelTypeVar.get()
                WaterCueType = WaterCueTypeVar.get()

                # Declar local variables for this task
                TrialNum=0
                CorrectNum=0
                MissNum=0
                TouchNum=0
                CorrectRate=0
                Writer_TouchEventTxt = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) +  " Touch.txt", 'w')  # Initialize the text exporter
                Writer_TouchEventCsv = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) +  " Touch.csv", 'w')  # Initialize the text exporter
                StartLickRecording()
                TaskDur = 0

                LightCycleControlOff()
                DoneCorrectResponse = 1
                RoofLightOff()
                InfraredLightOn()
                if WaterCueType == 'Normal':
                    DigitalOutOn(10)
                if WaterCueType == 'Blink':
                    DigitalOutBlinkOn(10)
                ServoPosInside(3)
                NowDrinking = 0
                NowPunishing = 0
                AutoWaterSupplyNum = 0
                AWS_Latency=20
                StartRecording()    # Start camera capturing and sending of TTL
                CntResetBook=1

                if PanelType == 'Normal':
                    CreateNormalPanel(0)
                if PanelType == 'Blink':
                    CreateBlinkPanel(0)
                if PanelType == 'Textured':
                    CreateTexturedPanel(0,0)

                Writer_TouchEventTxt.write('TrialNum\tResult\t\t\tyyyy/mm/dd\th:m\ts\n')  # Write item name
                TrialNum=0

                Timer_Start(5)  # Task time limit timer start
                Phase2 = 2
                if TaskType == "Devaluation":
                    Phase2 = 0
                Phase2_Init = 1
                print("Task #" + str(GetTaskID()) + " is started at " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(
                    GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

            if Phase2 == 0:   # Initiation of new trial
                TaskDur = Timer_GetSec(5)
                DoneCorrectResponse=0
                ShowPanel(0)
                TrialNum += 1
                Timer_Start(0)  # Start the latency timer
                #print(GetTimerStat(1))
                if CntResetBook==1:  # If the timer is stopped
                    #print("timer1start")
                    Timer_Start(1)  # Start the panel present duration timer
                    #print(GetTimerStat(1))
                if TaskType == 'Train(RI)' and CntResetBook==1:
                    CurrRandomInterval=RandomInterval*random.random()
                    print("Delay for correct touch: "+str(round(CurrRandomInterval,1))+" sec")
                    if CntResetBook==1:
                        CntResetBook=0
                if TaskType == 'Train(RR)':
                    IsRewardedTrial = 0
                    if RandomRate >= random.random()*100:
                        IsRewardedTrial=1
                Phase2 += 1
            if Phase2 == 1:   # Panel presentation
                Trg=0
                TouchedPanelID = DetectRoiNosepoke()  # Examine which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID != -1 and TouchedPanelID != 19:
                    #ShowTouchSymbol(30)
                    if TaskType == 'Train(RI)':
                        if Timer_GetSec(1) >= CurrRandomInterval:
                            print("Correct (Latency: "+str(Timer_GetSec(1))+" sec)")
                            Trg=1
                        if Timer_GetSec(1) < CurrRandomInterval:
                            print("Miss (Latency: "+str(Timer_GetSec(1))+" sec)")
                            Trg=-1
                    if TaskType == 'Train(RR)':
                        if IsRewardedTrial == 1:
                            Trg = 1
                        if IsRewardedTrial == 0:
                            Trg = -1
                    if TaskType == 'Devaluation':
                        print("Miss")
                        Trg=-1
                    if TaskType == 'Omission':
                        print("Miss ("+str(Timer_GetSec(1))+" sec past)")
                        Trg=-1
                if TaskType == 'Omission':  # If mouse holds without touching
                    if Timer_GetSec(1) >= PresentDur:
                        print("CorrectOmission ("+str(Timer_GetSec(1))+" sec past)")
                        Trg = 1
                if Trg==1:  # If mouse took correct response
                    DoneCorrectResponse = 1
                    ServoPosInside(3)  # Move water nozzle to the inside position
                    if WaterCueType == 'Normal':
                        DigitalOutOn(10)
                    if WaterCueType == 'Blink':
                        DigitalOutBlinkOn(10)
                    NowDrinking = 0
                    CorrectNum += 1  # Increase the number of correct response
                    TouchNum += 1
                    if TaskType == 'Train(RI)' or 'Train(RR)':
                        mOngoingResultVar.set('CorrectNum:' + str(CorrectNum) + '  Miss:' + str(MissNum) + '  Total:' + str(TouchNum) + '  Correct/Touch:' + str(round(CorrectNum / TouchNum * 100, 1)))
                        Writer_TouchEventTxt.write(str(TrialNum) + '\tCorrectTouch\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',1,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000))  # Write the response on the csv file
                    if TaskType == 'Omission':
                        mOngoingResultVar.set('CorrectOmission:' + str(CorrectNum) + '  Miss:' + str(MissNum) + '  Total:' + str(TouchNum) + '  Correct/Touch:' + str(round(CorrectNum / TouchNum * 100, 1)))
                        Writer_TouchEventTxt.write(str(TrialNum) + '\tCorrectOmission\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',1,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000)+ "\n")  # Write the response on the csv file
                    HidePanel(0)
                    Timer_End(0)
                    Timer_End(1)
                    CntResetBook = 1
                    if WaterCueType == 'Normal':
                        DigitalOutOn(10)
                    if WaterCueType == 'Blink':
                        DigitalOutBlinkOn(10)
                    Phase2 = 2  # Start reward phase
                if Trg==-1: # If mouse took wrong response
                    NowPunishing = 1
                    ServoPosOutside(3)
                    MissNum += 1
                    TouchNum += 1
                    if TaskType == 'Train(RI)' or 'Train(RR)':
                        mOngoingResultVar.set('Correct:' + str(CorrectNum) + '  Miss:'+str(MissNum) + '  Total:' + str(TouchNum) +'  Correct/Touch:' + str(round(CorrectNum/TouchNum*100,1)))
                        Writer_TouchEventTxt.write(str(TrialNum) + '\tMissTouch\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000)+"\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',0,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000))  # Write the response on the csv file
                    if TaskType == 'Devaluation':
                        mOngoingResultVar.set('Miss:'+str(MissNum) )
                        Writer_TouchEventTxt.write(str(TrialNum) + '\tMissTouch\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000)+"\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',0,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000)+ "\n")  # Write the response on the csv file
                    if TaskType == 'Omission':
                        Timer_End(1)
                        Timer_Start(1)
                        CntResetBook = 1
                        mOngoingResultVar.set('CorrectOmission:' + str(CorrectNum) + '  Miss:'+str(MissNum) + '  Total:' + str(TouchNum) +'  Correct/Touch:' + str(round(CorrectNum/TouchNum*100,1)))
                        Writer_TouchEventTxt.write(str(TrialNum) + '\tMissTouch\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000)+"\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',0,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000)+ "\n")  # Write the response on the csv file

                    HidePanel(0)
                    Timer_End(0)    # End timer1
                    Timer_Start(0)  # Start punish timer
                    Phase2 = 5 # Start punishment phase

                if Timer_GetSec(5) >= TimeLimit * 60:   # If time limit is exceeded
                    TaskDur = Timer_GetSec(5)
                    Timer_End(5)
                    Phase2 = 6
            if Phase2 == 2:  # Reward phase
                if DetectRoiNosepoke() == 19 and NowDrinking == 0:    # If the mouse initiates nose poke
                    NowDrinking = 1
                    Timer_Start(0)  # Start lick timer
                if NowDrinking == 1:
                    if DoneCorrectResponse == 1 and Timer_GetSec(0) >= LickDur:   # If lick time exceed the designated time
                        Timer_End(0) # End lick timer
                        ServoPosMiddle(3)    # Move water nozzle to the intermediate position
                        DigitalOutOff(10)
                        NowDrinking = 0
                        Timer_Start(0)  # Start ITI timer
                        Phase2 = 3
            if Phase2 == 3:   # ITI
                if Timer_GetSec(0) >= Iti:  # If ITI is passed
                    Timer_End(0)
                    Phase2 = 0  # Go to the next trial
                if CorrectNum >= MaxCorrectNum:
                    Timer_End(5)
                    Phase2=6 # Go to the task finish phase
            if Phase2 == 5:   # Punishment phase
                if Timer_GetSec(0) >= PunishDur:    # If punishment time is passed
                    NowPunishing = 0
                    ServoPosMiddle(3)    # Move water nozzle to the intermediate position
                    Timer_End(0)  # End punishment timer1
                    Timer_Start(0)  # Start ITI timer
                    Phase2 = 3
            if Phase2 == 6:
                HidePanel(0)
                if CorrectNum < MaxCorrectNum:    # If mouse didn't achieved the max correct response
                    Timer_Start(0)  # Timer for interval between task and arbitary water supply is started
                    Phase2 = 7
                if (CorrectNum == MaxCorrectNum) or TaskType == "Devaluation":    # If mouse achieved the max correct response
                    Phase2 = -1
            if Phase2 == 7:  # Wait until arbitary water suuply is started
                if Timer_GetSec(0) >= AWS_Latency:  # If the interval is past 60 20
                    Timer_End(0)
                    ArbitaryWaterSupplyDur = (MaxCorrectNum - CorrectNum) * LickDur * 1000  # Caliculate duration of complement water supply
                    if WaterCueType == 'Normal':
                        StartArbitaryWaterSupply(3,10,0,ArbitaryWaterSupplyDur) # Start complement water supply
                    if WaterCueType == 'Blink':
                        StartArbitaryWaterSupply(3,10,1,ArbitaryWaterSupplyDur) # Start complement water supply
                    #print("AWSstart")
                    Phase2 = 8
            if Phase2 == 8:
                if GetArbitaryWaterSupplyStat() == 1:  # If complement water supply is finished
                    Phase2 = -1

            if Phase2 == -1 or GetEndTaskNowButtonStat() == 1:  # Task finish phase   #
                LightCycleControlOn()
                ServoPosMiddle(3)
                #if Panel!=null:
                DeleteAllPanel()
                InfraredLightOff()
                NowPunishing = 0
                if GetRecordingStat() == 1:
                    SetEndRecordingTimer(60)
                if CorrectNum > 0 or MissNum > 0:
                    if TaskType !="Devaluation":
                        CorrectRate = int(CorrectNum * 100.0 / TouchNum)
                    Writer_TouchEventTxt.write('TotalNum:'+str(TouchNum)+'  Correct num:'+str(CorrectNum)+'  Incorrect num:'+str(MissNum)+'  Correct rate'+str(CorrectRate)+'%'+"\n")   #結果テキストの一番最後に成績のまとめを記入
                Writer_TouchEventTxt.write('SessionStartTime: ' + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()) + "\n")
                Writer_TouchEventTxt.write('SessionEndTime: ' + str(TimeNow.month) + '/' + str(TimeNow.day) + ' ' + str(TimeNow.hour) + ':' + str(TimeNow.minute) + ':' + str(TimeNow.second + (TimeNow.microsecond // 1000) / 1000) + "\n")
                Writer_TouchEventTxt.write('TaskDuration(sec): ' + str(TaskDur) + "\n")
                Writer_TouchEventTxt.write('MaxCorrectNum: '+str(MaxCorrectNum)+"\n")
                Writer_TouchEventTxt.write('TimeLimit: ' + str(TimeLimit) + "\n")
                Writer_TouchEventTxt.write('RandomInterval: ' + str(RandomInterval) + "\n")
                Writer_TouchEventTxt.write('RandomRate: ' + str(RandomRate) + "\n")
                Writer_TouchEventTxt.write('PresentDur: ' + str(PresentDur)+"\n")
                Writer_TouchEventTxt.write('PunishDur: ' + str(PunishDur)+"\n")
                Writer_TouchEventTxt.write('Iti: ' + str(Iti)+"\n")
                Writer_TouchEventTxt.write('LickDur: ' + str(LickDur)+"\n")
                Writer_TouchEventTxt.write('NextTaskTh: ' + str(NextTaskTh)+"\n")
                Writer_TouchEventTxt.write('NextTask: ' + str(NextTask)+"\n")
                Writer_TouchEventTxt.write('TaskType: ' + str(TaskType)+"\n")
                Writer_TouchEventTxt.write('PunishLight: ' + str(PunishLight)+"\n")
                Writer_TouchEventTxt.write('PanelType: ' + str(PanelType)+"\n")
                Writer_TouchEventTxt.write('WaterCueType: ' + str(WaterCueType)+"\n")
                Writer_TouchEventTxt.write('RecordFPS: ' + str(GetRecordFps()) + "\n")
                Writer_TouchEventTxt.write('AWS_Latency: ' + str(AWS_Latency) + "\n")
                Writer_TouchEventTxt.write(GetRoiSensitivity() + "\n")
                Writer_TouchEventTxt.write(GetServoAngle() + "\n")

                Writer_TouchEventTxt.close()
                Writer_TouchEventCsv.close()
                EndLickRecording()
                if TaskType=='Train(RI)' or 'Train(RR)' or  TaskType=='Devaluation':
                    SendMail(DeviceNameVar.get() + ' finished task ' + str(GetTaskID()) + '. Correct:' + str(CorrectNum) + ' Miss:' + str(MissNum) + ' Correct/Touch:' + str(CorrectRate) + ' Dur:' + str(round(Timer_GetSec(5) / 60, 1)) + ' min', 'The task is finished.')
                if TaskType == 'Omission':
                    SendMail(DeviceNameVar.get() + ' finished task ' + str(GetTaskID()) + '. CorrectOmission:' + str(CorrectNum) + ' Miss:' + str(MissNum) + ' CorrectOmission/Touch:' + str(CorrectRate) + ' Dur:' + str(round(Timer_GetSec(5) / 60, 1)) + ' min', 'The task is finished.')

                if IsHousingAnalysis == 1 and Phase2 == -1:  # If it is housing analysis
                    if CorrectRate >= NextTaskTh:  # If the score exceed the criteria to switch the next task
                        SwitchTask(NextTask)  # Onset task switch trigger
                        print("Task is switched to task#" + str(NextTask) + "  " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

                if IsHousingAnalysis == 0:
                    RoofLightOn()
                Phase2 = 0
                Phase = 1  # Go back to the task-waiting phase
                Phase2_Init = 0
            SetDispVariable(0, 'Phase2', str(Phase2))  # Display "Phase2" value on the main window
    return




def Task13():   # Probabilistic spatial learning task
    global Phase
    Phase0_Init=0
    Phase1_Init=0
    Phase2_Init=0
    while EndFlag==0:
        OperantHouseUpdate()
        if GetBackButtonStat()==1:    # If "Back" button is clicked
            break   # Back to the task select phase
        if Phase == 0:  # Parameter inputs
            if Phase0_Init == 0:
                # Make GUI for the setting of the parameters for this task
                RemoveMainRightWidget() # Remove task buttons
                PutStartBackButton()    # Put start/back buttons

                ColumnWidth = 14
                Row = 0  # Begin a new line
                Column = 0

                mMaxCorrectNum = ttk.Label(MainWindowRightFrame, text='MaxCorrectNum', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                MaxCorrectNumVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iMaxCorrectNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxCorrectNumVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mMaxTrialNum = ttk.Label(MainWindowRightFrame, text='MaxTrialNum', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                MaxTrialNumVar = IntVar(MainWindowRoot)
                iMaxTrialNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxTrialNumVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mTimeLimit = ttk.Label(MainWindowRightFrame, text='TimeLimit(min)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                TimeLimitVar = DoubleVar(MainWindowRoot)
                iTimeLimit = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mPunishDur = ttk.Label(MainWindowRightFrame, text='PunishDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                PunishDurVar = DoubleVar(MainWindowRoot)
                iPunishDur = ttk.Entry(MainWindowRightFrame, textvariable=PunishDurVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mIti = ttk.Label(MainWindowRightFrame, text='ITI(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                ItiVar = DoubleVar(MainWindowRoot)
                iIti = ttk.Entry(MainWindowRightFrame, textvariable=ItiVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mLickDur = ttk.Label(MainWindowRightFrame, text='LickDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                LickDurVar = DoubleVar(MainWindowRoot)
                iLickDur = ttk.Entry(MainWindowRightFrame, textvariable=LickDurVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field

                Row += 2  # Begin a new line
                Column = 0

                mNextTaskTh = ttk.Label(MainWindowRightFrame, text='NextTaskTh(Correct%)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                NextTaskThVar = DoubleVar(MainWindowRoot)
                iNextTaskTh = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskThVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mNextTask = ttk.Label(MainWindowRightFrame, text='NextTask#', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                NextTaskVar = IntVar(MainWindowRoot)
                iNextTask = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mCorrectPos = ttk.Label(MainWindowRightFrame, text='CorrectPos', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                CorrectPosVar = StringVar(MainWindowRightFrame)  # Declare variable receiving value from the entry field
                tCorrectPos = OptionMenu(MainWindowRightFrame, CorrectPosVar, "0", "1").grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mRewardRateOfCorrectPos = ttk.Label(MainWindowRightFrame, text='Correct%ofCorrectPos', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                RewardRateOfCorrectPosVar = DoubleVar(MainWindowRoot)
                iRewardRateOfCorrectPos = ttk.Entry(MainWindowRightFrame, textvariable=RewardRateOfCorrectPosVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mRewardRateOfWrongPos = ttk.Label(MainWindowRightFrame, text='Correct%ofWrongPos', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                RewardRateOfWrongPosVar = DoubleVar(MainWindowRoot)
                iRewardRateOfWrongPos = ttk.Entry(MainWindowRightFrame, textvariable=RewardRateOfWrongPosVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mSeed = ttk.Label(MainWindowRightFrame, text='Seed', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                SeedVar = IntVar(MainWindowRoot)
                iSeed = ttk.Entry(MainWindowRightFrame, textvariable=SeedVar, width=ColumnWidth).grid(row=Row+1, column=Column)  # Place entry field

                Row += 2  # Begin a new line
                Column = 0

                mPanelType = ttk.Label(MainWindowRightFrame, text='PanelType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                PanelTypeVar = StringVar(MainWindowRightFrame)
                tPanelType = OptionMenu(MainWindowRightFrame, PanelTypeVar, "Normal", "Blink", "Textured").grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mWaterCueType = ttk.Label(MainWindowRightFrame, text='WaterCueType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                WaterCueTypeVar = StringVar(MainWindowRightFrame)
                tWaterCueType = OptionMenu(MainWindowRightFrame, WaterCueTypeVar, "Normal", "Blink").grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mLitPattern = ttk.Label(MainWindowRightFrame, text='LitPattern', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                LitPatternVar = StringVar(MainWindowRightFrame)
                tLitPattern = OptionMenu(MainWindowRightFrame, LitPatternVar, "Random", "All").grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mPunishWithLight = ttk.Label(MainWindowRightFrame, text='PunishWithLight', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                PunishWithLightVar = StringVar(MainWindowRightFrame)
                tPunishWithLight = OptionMenu(MainWindowRightFrame, PunishWithLightVar, "ON", "OFF").grid(row=Row+1, column=Column)  # Place entry field
                Column += 1  # Shift column
                mAwsOn = ttk.Label(MainWindowRightFrame, text='AWS', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                AwsOnVar = StringVar(MainWindowRightFrame)
                tAwsOn = OptionMenu(MainWindowRightFrame, AwsOnVar, "ON", "OFF").grid(row=Row+1, column=Column)  # Place entry field

                Str = "ParametersForTask" + str(GetTaskID())
                if os.path.exists(Str + '/MaxCorrectNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxCorrectNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxCorrectNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxCorrectNumVar.set(80)  # Default value

                if os.path.exists(Str + '/MaxTrialNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxTrialNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxTrialNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxTrialNumVar.set(110)  # Default value

                if os.path.exists(Str + '/TimeLimit.dat') == True:  # If save file exists
                    with open(Str + '/TimeLimit.dat', 'rb') as PickleInst[GetTaskID()]:
                        TimeLimitVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    TimeLimitVar.set(360)  # Default value

                if os.path.exists(Str + '/PunishDur.dat') == True:  # If save file exists
                    with open(Str + '/PunishDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishDurVar.set(15)  # Default value

                if os.path.exists(Str + '/Iti.dat') == True:  # If save file exists
                    with open(Str + '/Iti.dat', 'rb') as PickleInst[GetTaskID()]:
                        ItiVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    ItiVar.set(1)  # Default value
                if os.path.exists(Str + '/LickDur.dat') == True:  # If save file exists
                    with open(Str + '/LickDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        LickDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    LickDurVar.set(2)  # Default value

                if os.path.exists(Str + '/NextTaskTh.dat') == True:  # If save file exists
                    with open(Str + '/NextTaskTh.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskThVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskThVar.set(100)  # Default value
                if os.path.exists(Str + '/NextTask.dat') == True:  # If save file exists
                    with open(Str + '/NextTask.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskVar.set(13)  # Default value

                if os.path.exists(Str + '/CorrectPos.dat') == True:  # If save file exists
                    with open(Str + '/CorrectPos.dat', 'rb') as PickleInst[GetTaskID()]:
                        CorrectPosVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    CorrectPosVar.set(1)  # Default value

                if os.path.exists(Str + '/RewardRateOfCorrectPos.dat') == True:  # If save file exists
                    with open(Str + '/RewardRateOfCorrectPos.dat', 'rb') as PickleInst[GetTaskID()]:
                        RewardRateOfCorrectPosVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    RewardRateOfCorrectPosVar.set(80)  # Default value

                if os.path.exists(Str + '/RewardRateOfWrongPos.dat') == True:  # If save file exists
                    with open(Str + '/RewardRateOfWrongPos.dat', 'rb') as PickleInst[GetTaskID()]:
                        RewardRateOfWrongPosVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    RewardRateOfWrongPosVar.set(20)  # Default value

                if os.path.exists(Str + '/Seed.dat') == True:  # If save file exists
                    with open(Str + '/Seed.dat', 'rb') as PickleInst[GetTaskID()]:
                        SeedVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    SeedVar.set(1)  # Default value

                if os.path.exists(Str + '/PanelType.dat') == True:  # If save file exists
                    with open(Str + '/PanelType.dat', 'rb') as PickleInst[GetTaskID()]:
                        PanelTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PanelTypeVar.set('Normal')  # Default value

                if os.path.exists(Str + '/WaterCueType.dat') == True:  # If save file exists
                    with open(Str + '/WaterCueType.dat', 'rb') as PickleInst[GetTaskID()]:
                        WaterCueTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    WaterCueTypeVar.set('Blink')  # Default value

                if os.path.exists(Str + '/LitPattern.dat') == True:  # If save file exists
                    with open(Str + '/LitPattern.dat', 'rb') as PickleInst[GetTaskID()]:
                        LitPatternVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    LitPatternVar.set('All')  # Default value
                if os.path.exists(Str + '/PunishWithLight.dat') == True:  # If save file exists
                    with open(Str + '/PunishWithLight.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishWithLightVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishWithLightVar.set('ON')  # Default value
                if os.path.exists(Str + '/AwsOn.dat') == True:  # If save file exists
                    with open(Str + '/AwsOn.dat', 'rb') as PickleInst[GetTaskID()]:
                        AwsOnVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    AwsOnVar.set('ON')  # Default value

                RemoveAllRoiGui()
                PutRoiGui(0, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(1, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(19, 0, 0, 1)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)

                RemoveAllDigitalOutGui()
                PutDigitalOutGui(10)
                PutDigitalOutGui(12)
                PutDigitalOutGui(13)

                RemoveAllServoGui()
                PutServoGui(3)

                Phase0_Init = 1

        if GetSaveTrgStat() == 1:    # If save trigger is on
            # Parameters of each task are saved into different folder
            Str="ParametersForTask"+str(GetTaskID())   # Path to the folder for saving of parameters
            if os.path.exists(Str) == False:    # If folder for saving parameters is not exist
                os.mkdir(Str)   # Make folder for saving
            with open(Str+'/MaxCorrectNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxCorrectNumVar.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/MaxTrialNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxTrialNumVar.get(),PickleInst[GetTaskID()])     # Save
            with open(Str + '/TimeLimit.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TimeLimitVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str+'/PunishDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishDurVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/Iti.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(ItiVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/LickDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(LickDurVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str + '/NextTask.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str+'/NextTaskTh.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskThVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/CorrectPos.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(CorrectPosVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/RewardRateOfCorrectPos.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(RewardRateOfCorrectPosVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/RewardRateOfWrongPos.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(RewardRateOfWrongPosVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/Seed.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(SeedVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/PanelType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PanelTypeVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/WaterCueType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(WaterCueTypeVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/LitPattern.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(LitPatternVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/PunishWithLight.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishWithLightVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/AwsOn.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(AwsOnVar.get(), PickleInst[GetTaskID()])     # Save

        if Phase == 1:  # Wait for starting of task
            if Phase1_Init == 0:
                PutPreTaskButton()
                mStatusVar = StringVar(MainWindowRoot)
                mStatus = ttk.Label(MainWindowRightFrame, textvariable=mStatusVar)
                mStatus.place(x=10, y=0)
                mOngoingResultVar = StringVar(MainWindowRoot)
                Phase1_Init = 1
            mStatusVar.set('Probabilistic spatial discrimination task (' + str(GetTaskID()) + ')    Waiting...')
            if IsStartTime() == 1:
                StartNow()
        if Phase == 2:  # During task
            if Phase2_Init == 0: # Initialization of the task
                PutEndTaskNowButton()

                mStatusVar.set('Probabilistic spatial discrimination task (' + str(GetTaskID()) + ')    Start time ' + str(TaskStartedMonth) + '/' + str(TaskStartedDay) + ' ' + str(TaskStartedHour) + ':' + str(TaskStartedMinute) + '    Running')
                mOngoingResult = ttk.Label(MainWindowRightFrame, textvariable=mOngoingResultVar)
                mOngoingResult.place(x=10, y=18)

                # Convert StringVars of parameters into integer or normal string to use in the following
                MaxCorrectNum=int(MaxCorrectNumVar.get())
                MaxTrialNum = int(MaxTrialNumVar.get())
                TimeLimit = float(TimeLimitVar.get())
                PunishDur = float(PunishDurVar.get())
                Iti = float(ItiVar.get())
                LickDur = float(LickDurVar.get())
                NextTask = int(NextTaskVar.get())
                NextTaskTh = float(NextTaskThVar.get())
                CorrectPos = CorrectPosVar.get()
                RewardRateOfCorrectPos =  float(RewardRateOfCorrectPosVar.get())
                RewardRateOfWrongPos = float(RewardRateOfWrongPosVar.get())
                Seed = int(SeedVar.get())
                PanelType = PanelTypeVar.get()
                WaterCueType =WaterCueTypeVar.get()
                LitPattern = LitPatternVar.get()
                PunishWithLight = PunishWithLightVar.get()
                AwsOn = AwsOnVar.get()

                StartLickRecording()
                RoofLightOff()
                InfraredLightOn()
                if WaterCueType == 'Normal':
                    DigitalOutOn(10)
                if WaterCueType == 'Blink':
                    DigitalOutBlinkOn(10)
                ServoPosInside(3)
                if PanelType=='Normal':
                    CreateNormalPanel(0)
                    CreateNormalPanel(1)
                if PanelType=='Blink':
                    CreateBlinkPanel(0)
                    CreateBlinkPanel(1)
                if PanelType=='Textured':
                    CreateTexturedPanel(0,0)
                    CreateTexturedPanel(1,0)

                # Declar local variables for this task
                TotalTouchNum = 0
                RewardNum = 0
                PunishNum = 0
                CorrectNum = 0
                RewardedCorrectNum = 0
                PunishedCorrectNum = 0
                WrongNum = 0
                RewardedWrongNum = 0
                PunishedWrongNum = 0
                CorrectRate = 0
                OnGoingResultUpdate = 0
                Rewarded = 0
                CorrectPanelRewardList = [0] * MaxTrialNum  # Keep which correct touch is rewarded or not
                WrongPanelRewardList = [0] * MaxTrialNum  # Keep which wrong touch is rewarded or not
                TotalRewardNumInCorrectList = int(MaxTrialNum * RewardRateOfCorrectPos /100)   # Rewarding schedule when mouse touches correct panel
                TotalRewardNumInWrongList = int(MaxTrialNum * RewardRateOfWrongPos / 100)   # Rewarding schedule when mouse touches wrong panel
                CurrRewardID_Correct = 0
                CurrRewardID_Wrong = 0
                TaskDur = 0

                # Make reward list when mouse touches correct panel
                random.seed(Seed)
                RewardFloatInterval = 1.0/float(RewardRateOfCorrectPos)*100.0
                print("Reward interval: "+str(RewardFloatInterval))
                CurrentTrialFloatNum = 0.0
                FailedNum = 0
                for i in range(TotalRewardNumInCorrectList):
                    for i2 in range(5):
                        r=int(CurrentTrialFloatNum + (random.random()*RewardFloatInterval))
                        if CorrectPanelRewardList[r]==0:
                            CorrectPanelRewardList[r] = 1
                            break
                        if i2 == 4:
                            FailedNum+=1
                    CurrentTrialFloatNum += RewardFloatInterval
                print("FailedNum:"+str(FailedNum))
                for i in range(FailedNum):
                    while True:
                        r = int(random.random()*MaxTrialNum)
                        if CorrectPanelRewardList[r]==0:
                            CorrectPanelRewardList[r] = 1
                            break
                for i in range(MaxTrialNum):
                    print("Correct:"+str(CorrectPanelRewardList[i]))


                # Make reward list when mouse touches wrong panel
                random.seed(Seed)
                RewardFloatInterval = 1.0 / float(RewardRateOfWrongPos) * 100.0
                print("Reward interval: "+str(RewardFloatInterval))
                CurrentTrialFloatNum = 0.0
                FailedNum = 0
                for i in range(TotalRewardNumInWrongList):
                    for i2 in range(5):
                        r = int(CurrentTrialFloatNum + (random.random() * RewardFloatInterval))
                        if WrongPanelRewardList[r] == 0:
                            WrongPanelRewardList[r] = 1
                            break
                        if i2 == 4:
                            FailedNum+=1
                    CurrentTrialFloatNum += RewardFloatInterval
                print("FailedNum:" + str(FailedNum))
                for i in range(FailedNum):
                    while True:
                        r = int(random.random()*MaxTrialNum)
                        if WrongPanelRewardList[r]==0:
                            WrongPanelRewardList[r] = 1
                            break
                for i in range(MaxTrialNum):
                    print("Wrong:"+str(WrongPanelRewardList[i]))

                    LightCycleControlOff()
                DoneCorrectResponse = 1
                NowDrinking = 0
                AWS_Latency=20
                StartRecording()    # Start camera capturing and sending of TTL

                TrialNum=0

                Timer_Start(5)  # Task time limit timer start
                Phase2 = 2
                Phase2_Init = 1

                Writer_TouchEventTxt = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.txt",'w')  # Initialize the text exporter
                Writer_TouchEventCsv = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.csv",'w')  # Initialize the text exporter
                Writer_TouchEventTxt.write('TrialNum\tResult\t\t\tyyyy/mm/dd\th:m\ts\n')  # Write item name
                print("Task #" + str(GetTaskID()) + " is started at " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

            if Phase2 == 0:   # Initiation of new trial
                TaskDur = Timer_GetSec(5)
                DoneCorrectResponse=0
                TrialNum += 1
                if LitPattern=='All':
                    ShowPanel(0)
                    ShowPanel(1)
                if LitPattern=='Random':
                    Rnd=random.random()*2
                    if Rnd < 1:
                        ShowPanel(0)
                    if Rnd >= 1:
                        ShowPanel(1)

                Timer_Start(0)  # Start the latency timer
                Phase2 += 1
            if Phase2 == 1:   # Panel presentation
                TouchedPanelID = DetectRoiNosepoke() # Examine which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID != -1 and TouchedPanelID != 19:

                    if TouchedPanelID == int(CorrectPos):  # If mouse touchs correct panel
                        CorrectResponse = 1
                        Rewarded = CorrectPanelRewardList[CurrRewardID_Correct]
                    if TouchedPanelID != int(CorrectPos):  # If mouse touchs incorrect panel
                        CorrectResponse = 0
                        Rewarded = WrongPanelRewardList[CurrRewardID_Wrong]

                    if Rewarded == 1: # If mouse touchs correct panel
                        DoneCorrectResponse = 1
                        ServoPosInside(3)  # Move water nozzle to the inside position
                        NowDrinking = 0
                        TotalTouchNum += 1
                        RewardNum += 1
                        if CorrectResponse == 1:
                            CorrectNum += 1 # Increase the number of correct respon
                            RewardedCorrectNum += 1
                            Writer_TouchEventTxt.write(str(TrialNum) + '\tPanelTouched(RewardedCorrect)\t' +str(TouchedPanelID)+'\t'+ str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the text file
                            Writer_TouchEventCsv.write(str(TrialNum) + ',1,' +str(TouchedPanelID)+','+ str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the csv file
                            CurrRewardID_Correct += 1
                        if CorrectResponse == 0:
                            WrongNum += 1  # Increase the number of wrong respon
                            RewardedWrongNum += 1
                            Writer_TouchEventTxt.write(str(TrialNum) + '\tPanelTouched(RewardedWrong)\t' +str(TouchedPanelID)+'\t'+ str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the text file
                            Writer_TouchEventCsv.write(str(TrialNum) + ',2,' +str(TouchedPanelID)+','+ str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the csv file
                            CurrRewardID_Wrong += 1
                        OnGoingResultUpdate=1
                        HidePanel(0)
                        HidePanel(1)
                        Timer_End(0)
                        if WaterCueType == 'Normal':
                            DigitalOutOn(10)
                        if WaterCueType == 'Blink':
                            DigitalOutBlinkOn(10)
                        Phase2 = 2  # Start reward phase
                    if Rewarded == 0: # If mouse touchs wrong panel
                        ServoPosOutside(3)
                        if PunishWithLight == 'ON':
                            RoofLightOn()  # Turn on roof light
                        TotalTouchNum += 1
                        PunishNum += 1
                        if CorrectResponse == 1:
                            CorrectNum += 1  # Increase the number of correct respon
                            PunishedCorrectNum += 1
                            Writer_TouchEventTxt.write(str(TrialNum) + '\tPanelTouched(PunishedCorrect)\t' +str(TouchedPanelID)+'\t'+ str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the text file
                            Writer_TouchEventCsv.write(str(TrialNum) + ',3,' +str(TouchedPanelID)+','+ str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the csv file
                            CurrRewardID_Correct += 1
                        if CorrectResponse == 0:
                            WrongNum += 1    # Increase the number of wrong respon
                            PunishedWrongNum += 1
                            Writer_TouchEventTxt.write(str(TrialNum) + '\tPanelTouched(PunishedWrong)\t' +str(TouchedPanelID)+'\t'+ str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the text file
                            Writer_TouchEventCsv.write(str(TrialNum) + ',4,' +str(TouchedPanelID)+','+ str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000) + "\n")  # Write the response on the csv file
                            CurrRewardID_Wrong += 1
                        OnGoingResultUpdate = 1
                        HidePanel(0)
                        HidePanel(1)
                        Timer_End(0)  # End timer1
                        Timer_Start(0)  # Start punish timer
                        Phase2 = 5  # Start punishment phase
                    if OnGoingResultUpdate == 1:
                        mOngoingResultVar.set('CorrectNum:' + str(CorrectNum) +' (Rewarded: '+str(RewardedCorrectNum)+ ', Punished: '+str(PunishedCorrectNum)+')  WrongNum:' + str(WrongNum)  +' (Rewarded: '+str(RewardedWrongNum)+ ', Punished: '+str(PunishedWrongNum) + ')  TotalNum:' + str(TotalTouchNum) + '  Correct:' + str(round(CorrectNum * 100.0 / TotalTouchNum, 2)) + '%')
                if Timer_GetSec(5) >= TimeLimit * 60:   # If time limit is exceeded
                    TaskDur = Timer_GetSec(5)
                    Timer_End(5)
                    Phase2 = 6
            if Phase2 == 2:  # Reward phase
                if DetectRoiNosepoke() == 19 and NowDrinking == 0:    # If the mouse initiates nose poke
                    NowDrinking = 1
                    Timer_Start(0)  # Start lick timer
                if NowDrinking == 1:
                    if DoneCorrectResponse == 1 and Timer_GetSec(0) >= LickDur:   # If lick time exceed the designated time
                        Timer_End(0) # End lick timer
                        ServoPosMiddle(3)    # Move water nozzle to the intermediate position
                        DigitalOutOff(10)
                        NowDrinking = 0
                        Timer_Start(0)  # Start ITI timer
                        Phase2 = 3

            if Phase2 == 3:   # ITI
                if Timer_GetSec(0) >= Iti:  # If ITI is passed
                    Timer_End(0)
                    Phase2 = 0  # Go to the next trial
                if RewardNum >= MaxCorrectNum or TotalTouchNum >= MaxTrialNum: # If mouse achieved criteria of finishing the task
                    Timer_End(5)
                    ServoPosMiddle(3)
                    DigitalOutOff(10)
                    Timer_Start(0)  # Timer for interval between task and arbitary water supply is started
                    Phase2 = 6  # Go to the AWS
            if Phase2 == 5:   # Punishment phase
                if Timer_GetSec(0) >= PunishDur:    # If punishment time is passed
                    RoofLightOff()
                    ServoPosMiddle(3)    # Move water nozzle to the intermediate position
                    Timer_End(0)  # End punishment timer1
                    Timer_Start(0)  # Start ITI timer
                    Phase2 = 3
            if Phase2==6:
                HidePanel(0)
                HidePanel(1)
                if RewardNum < MaxCorrectNum and AwsOn=='ON':  # If mouse didn't achieved the max correct response
                    Timer_Start(0)
                    Phase2 = 7
                if RewardNum == MaxCorrectNum or AwsOn=='OFF':  # If mouse achieved the max correct response
                    Phase2 = -1
            if Phase2==7:   # Wait until arbitary water suuply is started
                if Timer_GetSec(0) >= 20:   # If the interval is past 60
                    Timer_End(0)
                    ArbitaryWaterSupplyDur=(MaxCorrectNum - RewardNum) * LickDur * 1000    # Caliculate duration of complement water supply
                    if WaterCueType == 'Normal':
                        StartArbitaryWaterSupply(3,10,0,ArbitaryWaterSupplyDur) # Start complement water supply
                    if WaterCueType == 'Blink':
                        StartArbitaryWaterSupply(3,10,1,ArbitaryWaterSupplyDur) # Start complement water supply
                    print("AWSstart")
                    Phase2=8
            if Phase2==8:
                if GetArbitaryWaterSupplyStat()==1: # If complement water supply is finished
                    Phase2 = -1

            if Phase2 == -1 or GetEndTaskNowButtonStat() == 1:  # Task finish phase
                LightCycleControlOn()
                ServoPosMiddle(3)
                DeleteAllPanel()
                InfraredLightOff()
                if GetRecordingStat() == 1:
                    SetEndRecordingTimer(60)
                if CorrectNum > 0 or WrongNum > 0:
                    CorrectRate = int(CorrectNum * 100.0 / TotalTouchNum)
                    Writer_TouchEventTxt.write('TotalNum:'+str(TotalTouchNum)+'  Correct num:'+str(CorrectNum) +' (Rewarded: '+str(RewardedCorrectNum)+ ', Punished: '+str(PunishedCorrectNum)+')  WrongNum:' + str(WrongNum)  +' (Rewarded: '+str(RewardedWrongNum)+ ', Punished: '+str(PunishedWrongNum) +')  Correct rate'+str(CorrectRate)+'%'+"\n")    #結果テキストの一番最後に成績のまとめを記入
                Writer_TouchEventTxt.write('SessionStartTime: ' + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()) + "\n")
                Writer_TouchEventTxt.write('SessionEndTime: ' + str(TimeNow.month) + '/' + str(TimeNow.day) + ' ' + str(TimeNow.hour) + ':' + str(TimeNow.minute) + ':' + str(TimeNow.second + (TimeNow.microsecond // 1000) / 1000) + "\n")
                Writer_TouchEventTxt.write('TaskDuration(sec): ' + str(TaskDur) + "\n")
                Writer_TouchEventTxt.write('MaxCorrectNum: '+str(MaxCorrectNum)+"\n")
                Writer_TouchEventTxt.write('MaxTrialNum: ' + str(MaxTrialNum) + "\n")
                Writer_TouchEventTxt.write('TimeLimit: ' + str(TimeLimit) + "\n")
                Writer_TouchEventTxt.write('PunishDur: ' + str(PunishDur) + "\n")
                Writer_TouchEventTxt.write('Iti: ' + str(Iti) + "\n")
                Writer_TouchEventTxt.write('LickDur: ' + str(LickDur) + "\n")
                Writer_TouchEventTxt.write('NextTask: ' + str(NextTask) + "\n")
                Writer_TouchEventTxt.write('NextTaskTh: ' + str(NextTaskTh)+"\n")
                Writer_TouchEventTxt.write('CorrectPos: ' + str(CorrectPos) + "\n")
                Writer_TouchEventTxt.write('RewardRateOfCorrectPos: ' + str(RewardRateOfCorrectPos) + "\n")
                Writer_TouchEventTxt.write('RewardRateOfWrongPos: ' + str(RewardRateOfWrongPos) + "\n")
                Writer_TouchEventTxt.write('Seed: ' + str(Seed) + "\n")
                Writer_TouchEventTxt.write('PanelType: ' + str(PanelType) + "\n")
                Writer_TouchEventTxt.write('WaterCueType: ' + str(WaterCueType) + "\n")
                Writer_TouchEventTxt.write('LitPattern: ' + str(LitPattern) + "\n")
                Writer_TouchEventTxt.write('PunishLight: ' + str(PunishWithLight)+"\n")
                Writer_TouchEventTxt.write('RecordFPS: ' + str(GetRecordFps()) + "\n")
                Writer_TouchEventTxt.write('AWS: ' + AwsOn + "\n")
                Writer_TouchEventTxt.write('AWS_Latency: ' + str(AWS_Latency) + "\n")
                Writer_TouchEventTxt.write(GetRoiSensitivity() + "\n")
                Writer_TouchEventTxt.write(GetServoAngle() + "\n")

                Writer_TouchEventTxt.close()
                Writer_TouchEventCsv.close()
                EndLickRecording()
                #SendMail()
                SendMail(DeviceNameVar.get() + ' finished task '+str(GetTaskID())+'. Correct:' + str(CorrectNum) +'('+ str(RewardedCorrectNum)+'-'+str(PunishedCorrectNum)+') Wrong:' + str(WrongNum) +'('+str(RewardedWrongNum)+'-'+str(PunishedWrongNum)+') Correct:'+str(CorrectRate)+'% Dur:' + str(round(Timer_GetSec(5) / 60,1)) + ' min', 'The task is finished.')

                if IsHousingAnalysis == 1 and Phase2 == -1:  # If it is housing analysis
                    if CorrectRate >= NextTaskTh:  # If the score exceed the criteria to switch the next task
                        SwitchTask(NextTask)  # Onset task switch trigger
                        print("Task is switched to task#" + str(NextTask) + "  " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

                if IsHousingAnalysis == 0:
                    RoofLightOn()
                Phase = 1  # Go back to the task-waiting phase
                Phase2 = 0
                Phase2_Init = 0
            SetDispVariable(0, 'Phase2', str(Phase2))  # Display "Phase2" value on the main window
    return

def Task14():     # 2-step probabilistic spatial reversal learning task
    global Phase, Phase2, Init, Task, SaveTrg, NosePoking, DuringTask, NowRecording
    Task = 50
    Phase0_Init = 0
    Phase1_Init = 0
    Phase2_Init = 0
    while EndFlag == 0:
        OperantHouseUpdate()
        if Phase == -1:  # Back to the task select phase
            Phase = 0
            Task = 0
            break
        if Phase == 0:  # Parameter inputs
            if Phase0_Init == 0:
                # Make GUI for the setting of the parameters for this task
                RemoveMainRightWidget()  # Remove task buttons

                PutStartBackButton()  # Put start/back buttons
                mSpace = ttk.Label(MainWindowRightFrame, text='').grid(row=0, column=1)  # Used just as spacer

                mMaxRewardNum = ttk.Label(MainWindowRightFrame, text='MaxRewardNum').grid(row=0, column=2, sticky=W)  # Put label
                MaxRewardNumVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iMaxRewardNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxRewardNumVar).grid(row=1,column=2)  # Place entry field

                mMaxTrialNum = ttk.Label(MainWindowRightFrame, text='MaxTrialNum').grid(row=0, column=3, sticky=W)
                MaxTrialNumVar = IntVar(MainWindowRoot)
                iMaxTrialNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxTrialNumVar).grid(row=1, column=3)

                mTimeLimit = ttk.Label(MainWindowRightFrame, text='TimeLimitInPhase(min)').grid(row=0, column=4, sticky=W)
                TimeLimitVar = DoubleVar(MainWindowRoot)
                iTimeLimit = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitVar).grid(row=1, column=4)

                mPunishDur = ttk.Label(MainWindowRightFrame, text='PunishDur(s)').grid(row=0, column=5, sticky=W)
                PunishDurVar = DoubleVar(MainWindowRoot)
                iPunishDur = ttk.Entry(MainWindowRightFrame, textvariable=PunishDurVar).grid(row=1, column=5)

                mIti = ttk.Label(MainWindowRightFrame, text='ITI(s)').grid(row=0, column=6, sticky=W)
                ItiVar = DoubleVar(MainWindowRoot)
                iIti = ttk.Entry(MainWindowRightFrame, textvariable=ItiVar).grid(row=1, column=6)

                mLickDur = ttk.Label(MainWindowRightFrame, text='LickDur(s)').grid(row=0, column=7, sticky=W)
                LickDurVar = DoubleVar(MainWindowRoot)
                iLickDur = ttk.Entry(MainWindowRightFrame, textvariable=LickDurVar).grid(row=1, column=7)

                mEvalCorrectNum = ttk.Label(MainWindowRightFrame, text='EvalCorrectNum').grid(row=2, column=2, sticky=W)
                EvalCorrectNumVar = IntVar(MainWindowRoot)
                iEvalCorrectNum = ttk.Entry(MainWindowRightFrame, textvariable=EvalCorrectNumVar).grid(row=3, column=2)

                mNecCorrectNum = ttk.Label(MainWindowRightFrame, text='NecCorrectNum').grid(row=2, column=3, sticky=W)
                NecCorrectNumVar = IntVar(MainWindowRoot)
                iNecCorrectNum = ttk.Entry(MainWindowRightFrame, textvariable=NecCorrectNumVar).grid(row=3, column=3)

                mCorrectPos = ttk.Label(MainWindowRightFrame, text='CorrectPos').grid(row=2, column=4,sticky=W)  # Put label
                CorrectPosVar = StringVar(MainWindowRightFrame)  # Declare variable receiving value from the entry field
                tCorrectPos = OptionMenu(MainWindowRightFrame, CorrectPosVar, "0", "2").grid(row=3, column=4)  # Place drop-down list

                mRewardRateOfCorrectPos = ttk.Label(MainWindowRightFrame, text='Correct%ofCorrectPos').grid(row=2, column=5, sticky=W)
                RewardRateOfCorrectPosVar = DoubleVar(MainWindowRoot)
                iRewardRateOfCorrectPos = ttk.Entry(MainWindowRightFrame, textvariable=RewardRateOfCorrectPosVar).grid(row=3, column=5)

                mRewardRateOfWrongPos = ttk.Label(MainWindowRightFrame, text='Correct%ofWrongPos').grid(row=2, column=6, sticky=W)
                RewardRateOfWrongPosVar = DoubleVar(MainWindowRoot)
                iRewardRateOfWrongPos = ttk.Entry(MainWindowRightFrame, textvariable=RewardRateOfWrongPosVar).grid(row=3, column=6)

                mSeed = ttk.Label(MainWindowRightFrame, text='Seed').grid(row=2, column=7, sticky=W)
                SeedVar = IntVar(MainWindowRoot)
                iSeed = ttk.Entry(MainWindowRightFrame, textvariable=SeedVar).grid(row=3, column=7)

                mWaterCueType = ttk.Label(MainWindowRightFrame, text='WaterCueType').grid(row=4, column=3, sticky=W)
                WaterCueTypeVar = StringVar(MainWindowRightFrame)
                tWaterCueType = OptionMenu(MainWindowRightFrame, WaterCueTypeVar, "Normal", "Blink").grid(row=5,column=3)

                mPunishWithLight = ttk.Label(MainWindowRightFrame, text='PunishWithLight').grid(row=4, column=4,sticky=W)
                PunishWithLightVar = StringVar(MainWindowRightFrame)
                tPunishWithLight = OptionMenu(MainWindowRightFrame, PunishWithLightVar, "ON", "OFF").grid(row=5,column=4)

                mAwsOn = ttk.Label(MainWindowRightFrame, text='AWS').grid(row=4, column=5, sticky=W)
                AwsOnVar = StringVar(MainWindowRightFrame)
                iAwsOn = OptionMenu(MainWindowRightFrame, AwsOnVar, "ON", "OFF").grid(row=5, column=5)

                mTimeLimitDay = ttk.Label(MainWindowRightFrame, text='TimeLimitInDay(min)').grid(row=4, column=6, sticky=W)
                TimeLimitDayVar = DoubleVar(MainWindowRoot)
                iTimeLimitDay = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitDayVar).grid(row=5, column=6)

                Str = "ParametersForTask" + str(Task)
                if os.path.exists(Str + '/MaxRewardNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxRewardNum.dat', 'rb') as PickleInst[Task]:
                        MaxRewardNumVar.set(pickle.load(PickleInst[Task]))  # Load
                else:
                    MaxRewardNumVar.set(80)  # Default value

                if os.path.exists(Str + '/MaxTrialNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxTrialNum.dat', 'rb') as PickleInst[Task]:
                        MaxTrialNumVar.set(pickle.load(PickleInst[Task]))  # Load
                else:
                    MaxTrialNumVar.set(110)  # Default value

                if os.path.exists(Str + '/TimeLimit.dat') == True:  # If save file exists
                    with open(Str + '/TimeLimit.dat', 'rb') as PickleInst[Task]:
                        TimeLimitVar.set(pickle.load(PickleInst[Task]))  # Load
                else:
                    TimeLimitVar.set(90)  # Default value

                if os.path.exists(Str + '/TimeLimitDay.dat') == True:  # If save file exists
                    with open(Str + '/TimeLimitDay.dat', 'rb') as PickleInst[Task]:
                        TimeLimitDayVar.set(pickle.load(PickleInst[Task]))  # Load
                else:
                    TimeLimitDayVar.set(90)  # Default value

                if os.path.exists(Str + '/PunishDur.dat') == True:  # If save file exists
                    with open(Str + '/PunishDur.dat', 'rb') as PickleInst[Task]:
                        PunishDurVar.set(pickle.load(PickleInst[Task]))  # Load
                else:
                    PunishDurVar.set(15)  # Default value

                if os.path.exists(Str + '/Iti.dat') == True:  # If save file exists
                    with open(Str + '/Iti.dat', 'rb') as PickleInst[Task]:
                        ItiVar.set(pickle.load(PickleInst[Task]))  # Load
                else:
                    ItiVar.set(1)  # Default value
                if os.path.exists(Str + '/LickDur.dat') == True:  # If save file exists
                    with open(Str + '/LickDur.dat', 'rb') as PickleInst[Task]:
                        LickDurVar.set(pickle.load(PickleInst[Task]))  # Load
                else:
                    LickDurVar.set(2)  # Default value

                if os.path.exists(Str + '/EvalCorrectNum.dat') == True:  # If save file exists
                    with open(Str + '/EvalCorrectNum.dat', 'rb') as PickleInst[Task]:
                        EvalCorrectNumVar.set(pickle.load(PickleInst[Task]))  # Load
                else:
                    EvalCorrectNumVar.set(15)  # Default value
                if os.path.exists(Str + '/NecCorrectNum.dat') == True:  # If save file exists
                    with open(Str + '/NecCorrectNum.dat', 'rb') as PickleInst[Task]:
                        NecCorrectNumVar.set(pickle.load(PickleInst[Task]))  # Load
                else:
                    NecCorrectNumVar.set(12)  # Default value
                if os.path.exists(Str + '/CorrectPos.dat') == True:  # If save file exists
                    with open(Str + '/CorrectPos.dat', 'rb') as PickleInst[Task]:
                        CorrectPosVar.set(pickle.load(PickleInst[Task]))  # Load
                else:
                    CorrectPosVar.set(1)  # Default value
                if os.path.exists(Str + '/WaterCueType.dat') == True:  # If save file exists
                    with open(Str + '/WaterCueType.dat', 'rb') as PickleInst[Task]:
                        WaterCueTypeVar.set(pickle.load(PickleInst[Task]))  # Load
                else:
                    WaterCueTypeVar.set('Blink')  # Default value
                if os.path.exists(Str + '/PunishWithLight.dat') == True:  # If save file exists
                    with open(Str + '/PunishWithLight.dat', 'rb') as PickleInst[Task]:
                        PunishWithLightVar.set(pickle.load(PickleInst[Task]))  # Load
                else:
                    PunishWithLightVar.set('ON')  # Default value

                if os.path.exists(Str + '/AwsOn.dat') == True:  # If save file exists
                    with open(Str + '/AwsOn.dat', 'rb') as PickleInst[Task]:
                        AwsOnVar.set(pickle.load(PickleInst[Task]))  # Load
                else:
                    AwsOnVar.set('OFF')  # Default value

                if os.path.exists(Str + '/RewardRateOfCorrectPos.dat') == True:  # If save file exists
                    with open(Str + '/RewardRateOfCorrectPos.dat', 'rb') as PickleInst[Task]:
                        RewardRateOfCorrectPosVar.set(pickle.load(PickleInst[Task]))  # Load
                else:
                    RewardRateOfCorrectPosVar.set(80)  # Default value

                if os.path.exists(Str + '/RewardRateOfWrongPos.dat') == True:  # If save file exists
                    with open(Str + '/RewardRateOfWrongPos.dat', 'rb') as PickleInst[Task]:
                        RewardRateOfWrongPosVar.set(pickle.load(PickleInst[Task]))  # Load
                else:
                    RewardRateOfWrongPosVar.set(20)  # Default value

                RemoveAllRoiGui()
                PutRoiGui(0, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(1, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(2, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)
                PutRoiGui(19, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)

                RemoveAllDigitalOutGui()
                PutDigitalOutGui(10)
                PutDigitalOutGui(12)
                PutDigitalOutGui(13)

                RemoveAllServoGui()
                PutServoGui(3)

                Phase0_Init = 1

        if SaveTrg == 1:  # If save trigger is on
            # Parameters of each task are saved into different folder
            Str = "ParametersForTask" + str(Task)  # Path to the folder for saving of parameters
            if os.path.exists(Str) == False:  # If folder for saving parameters is not exist
                os.mkdir(Str)  # Make folder for saving
            with open(Str + '/MaxRewardNum.dat', 'wb') as PickleInst[Task]:
                pickle.dump(MaxRewardNumVar.get(), PickleInst[Task])  # Save
            with open(Str + '/MaxTrialNum.dat', 'wb') as PickleInst[Task]:
                pickle.dump(MaxTrialNumVar.get(), PickleInst[Task])  # Save
            with open(Str + '/TimeLimit.dat', 'wb') as PickleInst[Task]:
                pickle.dump(TimeLimitVar.get(), PickleInst[Task])  # Save
            with open(Str + '/TimeLimitDay.dat', 'wb') as PickleInst[Task]:
                pickle.dump(TimeLimitDayVar.get(), PickleInst[Task])  # Save
            with open(Str + '/PunishDur.dat', 'wb') as PickleInst[Task]:
                pickle.dump(PunishDurVar.get(), PickleInst[Task])  # Save
            with open(Str + '/Iti.dat', 'wb') as PickleInst[Task]:
                pickle.dump(ItiVar.get(), PickleInst[Task])  # Save
            with open(Str + '/LickDur.dat', 'wb') as PickleInst[Task]:
                pickle.dump(LickDurVar.get(), PickleInst[Task])  # Save
            with open(Str + '/EvalCorrectNum.dat', 'wb') as PickleInst[Task]:
                pickle.dump(EvalCorrectNumVar.get(), PickleInst[Task])  # Save
            with open(Str + '/NecCorrectNum.dat', 'wb') as PickleInst[Task]:
                pickle.dump(NecCorrectNumVar.get(), PickleInst[Task])  # Save
            with open(Str + '/CorrectPos.dat', 'wb') as PickleInst[Task]:
                pickle.dump(CorrectPosVar.get(), PickleInst[Task])  # Save
            with open(Str + '/WaterCueType.dat', 'wb') as PickleInst[Task]:
                pickle.dump(WaterCueTypeVar.get(), PickleInst[Task])  # Save
            with open(Str + '/PunishWithLight.dat', 'wb') as PickleInst[Task]:
                pickle.dump(PunishWithLightVar.get(), PickleInst[Task])  # Save
            with open(Str + '/AwsOn.dat', 'wb') as PickleInst[Task]:
                pickle.dump(AwsOnVar.get(), PickleInst[Task])  # Save
            with open(Str + '/RewardRateOfCorrectPos.dat', 'wb') as PickleInst[Task]:
                pickle.dump(RewardRateOfCorrectPosVar.get(), PickleInst[Task])  # Save
            with open(Str+'/RewardRateOfWrongPos.dat', 'wb') as PickleInst[Task]:
                pickle.dump(RewardRateOfWrongPosVar.get(), PickleInst[Task])     # Save
            SaveTrg = 0

        if Phase == 1:  # Wait for starting of task
            if Phase1_Init == 0:
                PutPreTaskButton()
                mStatusVar = StringVar(MainWindowRoot)
                mStatus = ttk.Label(MainWindowRightFrame, textvariable=mStatusVar)
                mStatus.place(x=10, y=0)
                mOngoingResultVar = StringVar(MainWindowRoot)
                Phase1_Init = 1
            mStatusVar.set('Probabilistic Reversal Task (' + str(Task) + ')    Waiting...')
            if IsStartTime() == 1:
                StartNow()

        if Phase == 2:  # During task
            if Phase2_Init == 0:  # Initialization of the task
                PutEndTaskNowButton()
                mStatusVar.set(
                    'Probabilistic Reversal Task (' + str(Task) + ')    Start time ' + str(TaskStartedMonth) + '/' + str(
                        TaskStartedDay) + ' ' + str(TaskStartedHour) + ':' + str(TaskStartedMinute) + '    Running')
                mOngoingResult = ttk.Label(MainWindowRightFrame, textvariable=mOngoingResultVar)
                mOngoingResult.place(x=10, y=18)

                # Convert StringVars of parameters into integer or normal string to use in the following
                MaxRewardNum = int(MaxRewardNumVar.get())
                MaxTrialNum = int(MaxTrialNumVar.get())
                TimeLimit = float(TimeLimitVar.get())
                TimeLimitDay = float(TimeLimitDayVar.get())
                PunishDur = float(PunishDurVar.get())
                Iti = float(ItiVar.get())
                LickDur = float(LickDurVar.get())

                EvalCorrectNum = int(EvalCorrectNumVar.get())
                NecCorrectNum = int(NecCorrectNumVar.get())

                CorrectPos = int(CorrectPosVar.get())
                WaterCueType = WaterCueTypeVar.get()
                PunishWithLight = PunishWithLightVar.get()
                AwsOn = AwsOnVar.get()

                RewardRateOfCorrectPos =  float(RewardRateOfCorrectPosVar.get())
                Seed = int(SeedVar.get())
                RewardRateOfWrongPos = float(RewardRateOfWrongPosVar.get())

                StartLickRecording()
                LightCycleControlOff()
                RoofLightOff()
                InfraredLightOn()
                if WaterCueType == 'Normal':
                    DigitalOutOn(10)
                if WaterCueType == 'Blink':
                    DigitalOutBlinkOn(10)
                ServoPosInside(3)
                CreateNormalPanel(0)
                CreateBlinkPanel(1)
                CreateNormalPanel(2)

                # Declar local variables for this task
                CorrectResponse = 0
                TouchNum = 0
                AdmittedCorrectNum = 0
                AdmittedWrongNum = 0
                AdmittedTouchNum = 0
                AdmittedCorrectRate = 0
                ResultLog = [0] * EvalCorrectNum
                ReversalNum = 0
                TrialPerReversal = 0  # Average trial number per reversal

                CorrectNum = 0
                RewardedCorrectNum = 0
                PunishedCorrectNum = 0
                WrongNum = 0
                RewardedWrongNum = 0
                PunishedWrongNum = 0
                CorrectRate = 0
                OnGoingResultUpdate = 0
                Rewarded = 0
                RewardNum = 0
                RecentCorrectNum = 0

                CorrectPanelRewardList = [0] * MaxTrialNum  # Keep which correct touch is rewarded or not
                WrongPanelRewardList = [0] * MaxTrialNum  # Keep which wrong touch is rewarded or not
                TotalRewardNumInCorrectList = int(MaxTrialNum * RewardRateOfCorrectPos / 100)  # Rewarding schedule when mouse touches correct panel
                TotalRewardNumInWrongList = int(MaxTrialNum * RewardRateOfWrongPos / 100)  # Re
                CurrRewardID_Correct = 0
                CurrRewardID_Wrong = 0

                PrematureTouchNum = 0
                LastTrialAtReversal = 0

                # Make reward list when mouse touches correct panel
                random.seed(Seed)
                RewardFloatInterval = 1.0 / float(RewardRateOfCorrectPos) * 100.0
                print("Reward interval: " + str(RewardFloatInterval))
                CurrentTrialFloatNum = 0.0
                FailedNum = 0
                for i in range(TotalRewardNumInCorrectList):
                    for i2 in range(5):
                        r = int(CurrentTrialFloatNum + (random.random() * RewardFloatInterval))
                        if CorrectPanelRewardList[r] == 0:
                            CorrectPanelRewardList[r] = 1
                            break
                        if i2 == 4:
                            FailedNum += 1
                    CurrentTrialFloatNum += RewardFloatInterval
                print("FailedNum:" + str(FailedNum))
                for i in range(FailedNum):
                    while True:
                        r = int(random.random() * MaxTrialNum)
                        if CorrectPanelRewardList[r] == 0:
                            CorrectPanelRewardList[r] = 1
                            break
                for i in range(MaxTrialNum):
                    print("Correct:" + str(CorrectPanelRewardList[i]))


                # Make reward list when mouse touches wrong panel
                if RewardRateOfWrongPos != 0:
                    random.seed(Seed)
                    RewardFloatInterval = 1.0 / float(RewardRateOfWrongPos) * 100.0
                    print("Reward interval: "+str(RewardFloatInterval))
                    CurrentTrialFloatNum = 0.0
                    FailedNum = 0
                    for i in range(TotalRewardNumInWrongList):
                        for i2 in range(5):
                            r = int(CurrentTrialFloatNum + (random.random() * RewardFloatInterval))
                            if WrongPanelRewardList[r] == 0:
                                WrongPanelRewardList[r] = 1
                                break
                            if i2 == 4:
                                FailedNum+=1
                        CurrentTrialFloatNum += RewardFloatInterval
                    print("FailedNum:" + str(FailedNum))
                    for i in range(FailedNum):
                        while True:
                            r = int(random.random()*MaxTrialNum)
                            if WrongPanelRewardList[r]==0:
                                WrongPanelRewardList[r] = 1
                                break
                    for i in range(MaxTrialNum):
                        print("Wrong:"+str(WrongPanelRewardList[i]))


                DuringTask = 1
                DoneCorrectResponse = 1
                NowDrinking = 0
                AWS_Latency = 20
                StartRecording()  # Start camera capturing and sending of TTL

                ReTry=0 # 1 just after premature touch
                TrialNum = 0


                Phase2 = 4 #Start from rewarding once
                Phase2_Init = 1

                Writer_TouchEventTxt = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(Task) + " Touch.txt",'w')  # Initialize the text exporter
                Writer_TouchEventCsv = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(Task) + " Touch.csv",'w')  # Initialize the text exporter
                Writer_TouchEventTxt.write('TrialNum\tNetReversalNum\tLastTrialAtReversal\tCorrectOrNot\tCorrectPos\tResult\t\t\tyyyy/mm/dd\th:m\ts\n')  # Write item name
                print("Task #" + str(Task) + " is started at " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

                Timer_End(7)
                Timer_Start(7)

            if Phase2 == 0:  # Initiation of new trial with center presentation
                DoneCorrectResponse = 0
                if Timer_GetSec(7) >= TimeLimitDay * 60:   # If time limit for day is exceeded
                    Timer_End(7)
                    Phase2 = 7

                Timer_End(5)
                Timer_Start(5)  # Phase time limit timer start

                if ReTry!=1:
                    TrialNum += 1
                HidePanel(0)
                ShowPanel(1)
                HidePanel(2)
                Timer_Start(0)  # Start the latency timer
                Phase2 = 1

            if Phase2 == 1:
                TouchedPanelID = DetectRoiNosepoke()  # Examine which panel is touched (return panel ID. If none of the panels touched, return -1)
                if Timer_GetSec(5) >= TimeLimit * 60:  # If time limit is exceeded
                        Timer_End(5)
                        Timer_End(0)  # End timer
                        Timer_Start(0)  # Start timer
                        Phase2 = 6  # ITI

                if Timer_GetSec(7) >= TimeLimitDay * 60:   # If time limit for day is exceeded
                    Timer_End(7)
                    Phase2 = 7

                if TouchedPanelID != -1:  # If mouse touchs any panel
                    if TouchedPanelID == 1: # If mouse touched center panel
                        HidePanel(1)
                        Writer_TouchEventTxt.write(str(TrialNum) +"\t" + str(ReversalNum) +"\t" + str(LastTrialAtReversal) +"\t0\t" + str(CorrectPos) + '\tCenterTouch\t' + str(TouchedPanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ","  + str(ReversalNum)+ "," + str(LastTrialAtReversal)+ ",0," +str(CorrectPos) + ",10," + str(TouchedPanelID) + ","  + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file

                        Timer_End(0)  # End timer
                        ShowPanel(0)
                        ShowPanel(2)
                        Timer_Start(0)  # Start timer
                        Phase2 = 2  # Go to next step

                    if TouchedPanelID == 0 or TouchedPanelID == 2:  # If mouse touched side panel
                        HidePanel(1)
                        PrematureTouchNum +=1
                        Writer_TouchEventTxt.write(str(TrialNum) +"\t" + str(ReversalNum) +"\t" + str(LastTrialAtReversal) +"\t0\t" + str(CorrectPos)  +'\tPrematureTouch\t' + str(TouchedPanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ","  + str(ReversalNum)+ "," + str(LastTrialAtReversal)+ ",0," + str(CorrectPos)+ ',11,' + str(TouchedPanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                        Timer_End(0)  # End timer

                        if PunishWithLight == 'ON':
                            RoofLightOn()  # Turn on roof light
                        Timer_Start(0)  # Start timer
                        Phase2 = 50

            if Phase2 == 50:  # Punish after premature touch
                if Timer_GetSec(0) >= PunishDur:  # If punishment time is passed
                    RoofLightOff()
                    ServoPosMiddle(3)  # Move water nozzle to the intermediate position
                    Timer_End(0)  # End punishment timer1
                    Timer_Start(0)  # Start ITI timer
                    Timer_End(5)
                    Timer_Start(5)
                    Phase2 = 0
                    ReTry=1

            if Phase2 == 2:  # Panel presentation
                TouchedPanelID = DetectRoiNosepoke()
                if Timer_GetSec(7) >= TimeLimitDay * 60:   # If time limit for day is exceeded
                    Timer_End(7)
                    Phase2 = 7

                if Timer_GetSec(5) >= TimeLimit * 60:  # If time limit is exceeded
                    Timer_End(5)
                    Timer_End(0)  # End timer
                    Timer_Start(0)  # Start time
                    Phase2 = 6  # ITI

                if TouchedPanelID != -1 and TouchedPanelID != 1 and TouchedPanelID != 19: # If mouse touchs side panel

                    if TouchedPanelID == int(CorrectPos) :  # If mouse touchs correct choice panel
                        CorrectResponse = 1
                        Rewarded = CorrectPanelRewardList[CurrRewardID_Correct]
                        TouchNum += 1
                        CorrectNum += 1
                        for i in range(EvalCorrectNum - 1):
                            ResultLog[EvalCorrectNum - 1 - i] = ResultLog[EvalCorrectNum - 1 - i - 1]  # Push the log
                        ResultLog[0] = 1  # Input current result

                    if TouchedPanelID != int(CorrectPos) :  # If mouse touchs wrong choice panel
                        CorrectResponse = 0
                        Rewarded = WrongPanelRewardList[CurrRewardID_Wrong]
                        WrongNum += 1
                        TouchNum += 1
                        for i in range(EvalCorrectNum - 1):
                            ResultLog[EvalCorrectNum - 1 - i] = ResultLog[EvalCorrectNum - 1 - i - 1]  # Push the log
                        ResultLog[0] = 0

                    if Rewarded == 1:  # If mouse gets reward
                       DoneCorrectResponse = 1
                       ServoPosInside(3)  # Move water nozzle to the inside position
                       NowDrinking = 0
                       RewardNum += 1

                       if CorrectResponse == 1: # Increase the number of correct respon
                            RewardedCorrectNum += 1
                            Writer_TouchEventTxt.write(str(TrialNum) +"\t" + str(ReversalNum) +"\t" + str(LastTrialAtReversal) +"\t1\t" +  str(CorrectPos) + '\tPanelTouched(RewardedCorrect)\t' + str(TouchedPanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                            Writer_TouchEventCsv.write(str(TrialNum) + ","  + str(ReversalNum)+ "," + str(LastTrialAtReversal)+ ",1," +  str(CorrectPos)  + ',20,' + str(TouchedPanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                            CurrRewardID_Correct += 1
                       if CorrectResponse == 0: # Increase the number of wrong respon
                           RewardedWrongNum += 1
                           Writer_TouchEventTxt.write(str(TrialNum) +"\t" + str(ReversalNum) +"\t" + str(LastTrialAtReversal) +"\t0\t" +  str(CorrectPos) + '\tPanelTouched(RewardedWrong)\t' + str(TouchedPanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                           Writer_TouchEventCsv.write(str(TrialNum) + ","  + str(ReversalNum)+ "," + str(LastTrialAtReversal)+ ",0," + str(CorrectPos) + ',21,' + str(TouchedPanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                           CurrRewardID_Wrong += 1

                       OnGoingResultUpdate = 1
                       HidePanel(0)
                       HidePanel(2)
                       Timer_End(0)
                       if WaterCueType == 'Normal':
                           DigitalOutOn(10)
                       if WaterCueType == 'Blink':
                           DigitalOutBlinkOn(10)
                       Phase2 = 4  # Start reward phase

                    if Rewarded == 0:  # If mouse didn't get reward
                        ServoPosOutside(3)
                        if PunishWithLight == 'ON':
                            RoofLightOn()  # Turn on roof light
                        if CorrectResponse == 1:
                            PunishedCorrectNum += 1
                            Writer_TouchEventTxt.write(str(TrialNum) +"\t" + str(ReversalNum) +"\t" + str(LastTrialAtReversal) +"\t1\t" + str(CorrectPos) + '\tPanelTouched(PunishedCorrect)\t' + str(TouchedPanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                            Writer_TouchEventCsv.write(str(TrialNum) + ","  + str(ReversalNum)+ "," + str(LastTrialAtReversal)+ ",1," +  str(CorrectPos) + ',22,' + str(TouchedPanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                            CurrRewardID_Correct += 1
                        if CorrectResponse == 0:
                            PunishedWrongNum += 1
                            Writer_TouchEventTxt.write(str(TrialNum) +"\t" + str(ReversalNum) +"\t" + str(LastTrialAtReversal) +"\t0\t" + str(CorrectPos) + '\tPanelTouched(PunishedWrong)\t' + str(TouchedPanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                            Writer_TouchEventCsv.write(str(TrialNum) + ","  + str(ReversalNum)+ "," + str(LastTrialAtReversal)+ ",0," + str(CorrectPos) + ',23,' + str(TouchedPanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")
                            CurrRewardID_Wrong += 1# Write the response on the csv file

                        OnGoingResultUpdate = 1
                        HidePanel(0)
                        HidePanel(2)
                        Timer_End(0)  # End timer1
                        Timer_Start(0)  # Start punish timer
                        Phase2 = 5  # Start punishment phase

                    if OnGoingResultUpdate == 1:
                        mOngoingResultVar.set('CorNum:' + str(CorrectNum) + ' (Rewarded: ' + str(RewardedCorrectNum) + ', Punished: ' + str(PunishedCorrectNum) + ')  WroNum:' + str(WrongNum) +'(Rewarded:'+str(RewardedWrongNum)+ ', Punished:'+str(PunishedWrongNum) + ') TotalNum:' + str(TouchNum) + ' \nAdmCor:' + str( AdmittedCorrectNum) + '  AdmWro:' + str(AdmittedWrongNum) + '  AdmTouch:' + str(AdmittedTouchNum) + '  AdmRate:' + str(AdmittedCorrectRate) + ' %' + '  Revers:' + str(ReversalNum) + '\nRecentCor:' + str(RecentCorrectNum))

            if Phase2 == 4:  # Reward phase
                TouchedPanelID = DetectRoiNosepoke()
                if TouchedPanelID == 19 and NowDrinking == 0:  # If the mouse initiates nose poke
                    NowDrinking = 1
                    Timer_Start(0)  # Start lick timer
                if NowDrinking == 1:
                    if DoneCorrectResponse == 1 and Timer_GetSec(0) >= LickDur:  # If lick time exceed the designated time
                        Timer_End(0)  # End lick timer
                        ServoPosMiddle(3)  # Move water nozzle to the intermediate position
                        DigitalOutOff(10)
                        NowDrinking = 0
                        Timer_Start(0)  # Start ITI timer
                        Phase2 = 6  # ITI
                if Timer_GetSec(7) >= TimeLimitDay * 60:   # If time limit for day is exceeded
                    Timer_End(7)
                    Phase2 = 7

            if Phase2 == 5:  # Punishment phase
                if Timer_GetSec(0) >= PunishDur:  # If punishment time is passed
                    RoofLightOff()
                    ServoPosMiddle(3)  # Move water nozzle to the intermediate position
                    Timer_End(0)  # End punishment timer1
                    Timer_Start(0)  # Start ITI timer
                    Phase2 = 6

            if Phase2 == 6: # ITI
                HideAllPanel()
                Timer_End(5)
                if Timer_GetSec(0) >= Iti:  # If ITI is passed
                    Timer_End(0)
                    # Count recent correct num (Evaluate latest EvaCorrectNum trials)
                    RecentCorrectNum = 0
                    for i in range(EvalCorrectNum):
                        if ResultLog[i] == 1:
                            RecentCorrectNum += 1
                    if RecentCorrectNum >= NecCorrectNum:
                        LastTrialAtReversal = TrialNum
                        ReversalNum += 1
                        Writer_TouchEventTxt.write(str(TrialNum) +"\t" + str(ReversalNum) +"\t" + str(LastTrialAtReversal) +"\t0\t" + str(CorrectPos) + '\tClearedAdmittedRate\t' + '\tNA\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ","  + str(ReversalNum)+ "," + str(LastTrialAtReversal)+ ",0," + str(CorrectPos) + ',50,NA,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")

                        AdmittedCorrectNum = CorrectNum
                        AdmittedWrongNum = WrongNum
                        AdmittedTouchNum = AdmittedCorrectNum + AdmittedWrongNum
                        if AdmittedTouchNum > 0:
                            AdmittedCorrectRate = round(AdmittedCorrectNum / AdmittedTouchNum * 100, 2)
                        if ReversalNum > 0:
                            TrialPerReversal = round(AdmittedTouchNum / ReversalNum, 2)

                        for i in range(EvalCorrectNum):
                            ResultLog[i] = 0
                        Trg = 0
                        if CorrectPos == 0:
                            CorrectPos = 2
                            Trg = 1
                        if CorrectPos == 2 and Trg == 0:
                            CorrectPos = 0

                    mOngoingResultVar.set('CorNum:' + str(CorrectNum) + ' (Rewarded: ' + str(RewardedCorrectNum) + ', Punished: ' + str(PunishedCorrectNum) + ')  WroNum:' + str(WrongNum) + '(Rewarded:' + str(RewardedWrongNum) + ', Punished:' + str(PunishedWrongNum) + ') TotalNum:' + str( TouchNum) + '\nAdmCor:' + str(AdmittedCorrectNum) + '  AdmWro:' + str(AdmittedWrongNum) + '  AdmTouch:' + str( AdmittedTouchNum) + '  AdmRate:' + str(AdmittedCorrectRate) + ' %' + '  Revers:' + str(ReversalNum) + '\nRecentCor:' + str(RecentCorrectNum))
                    ReTry = 0
                    Phase2 = 0  # Go to the next trial

                if Timer_GetSec(7) >= TimeLimitDay * 60:  # If time limit for day is exceeded
                    Timer_End(7)
                    Phase2 = 7

                if RewardNum >= MaxRewardNum or TouchNum >= MaxTrialNum:  # If mouse achieved criteria of finishing the task
                    ServoPosMiddle(3)
                    DigitalOutOff(10)

                    Timer_Start(0)  # Timer for interval between task and arbitary water supply is started
                    Phase2 = 7  # Go to the AWS

            if Phase2 == 7:  # AWS
                HidePanel(0)
                HidePanel(1)
                HidePanel(2)

                if RewardNum < MaxRewardNum and AwsOn == 'ON':  # If mouse didn't achieved the max correct response
                    Timer_Start(0)
                    Phase2 = 8
                if RewardNum == MaxRewardNum or AwsOn == 'OFF':  # If mouse achieved the max correct response
                    Phase2 = -1

            if Phase2 == 8:  # Wait until arbitary water suuply is started
                if Timer_GetSec(0) >= AWS_Latency:  # If the interval is past 60
                    Timer_End(0)
                    ArbitaryWaterSupplyDur = (MaxRewardNum - CorrectNum) * LickDur * 1000  # Caliculate duration of complement water supply
                    if WaterCueType == 'Normal':
                        StartArbitaryWaterSupply(3,10,0,ArbitaryWaterSupplyDur) # Start complement water supply
                    if WaterCueType == 'Blink':
                        StartArbitaryWaterSupply(3,10,1,ArbitaryWaterSupplyDur) # Start complement water supply
                    # print("AWSstart")
                    Phase2 = 9

            if Phase2 == 9:
                if GetArbitaryWaterSupplyStat() == 1:  # If complement water supply is finished
                    Phase2 = -1
            #print(Phase2)
            if Phase2 == -1 or GetEndTaskNowButtonStat() == 1:  # Task finish phase
                LightCycleControlOn()
                DuringTask = 0
                ServoPosMiddle(3)
                DeleteAllPanel()
                InfraredLightOff()
                if NowRecording == 1:
                    SetEndRecordingTimer(60)

                if CorrectNum > 0 or WrongNum > 0:
                    Writer_TouchEventTxt.write(
                        'Correct num:' + str(CorrectNum) + ' (Rewarded: ' + str(RewardedCorrectNum) + ', Punished: ' + str(PunishedCorrectNum) + ') Wrong num:' + str(WrongNum) + ' (Rewarded: ' + str(RewardedWrongNum) + ', Punished: ' + str(PunishedWrongNum) + ') TotalTouchNum:' + str(TouchNum) + '  AdmittedCorrect num:' + str(AdmittedCorrectNum) + '  AdmittedWrong num:' + str(AdmittedWrongNum) + '  AdmittedTouchNum:' + str( AdmittedTouchNum) + '  AdmittedCorrect rate:' + str(AdmittedCorrectRate) + '%  Reversal:' + str(ReversalNum) + '  Touch/Reversal:' + str(TrialPerReversal) + ', PrematureTouchNum:' +str(PrematureTouchNum) + "\n")    # Summary of result

                Writer_TouchEventTxt.write( 'TaskStartTime: ' + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()) + "\n")
                Writer_TouchEventTxt.write( 'TaskEndTime: ' + str(TimeNow.month) + '/' + str(TimeNow.day) + ' ' + str(TimeNow.hour) + ':' + str(TimeNow.minute) + ':' + str(TimeNow.second + (TimeNow.microsecond // 1000) / 1000) + "\n")
                Writer_TouchEventTxt.write('MaxRewardNum: ' + str(MaxRewardNum) + "\n")
                Writer_TouchEventTxt.write('MaxTrialNum: ' + str(MaxTrialNum) + "\n")
                Writer_TouchEventTxt.write('TimeLimitInTrial: ' + str(TimeLimit) + "\n")
                Writer_TouchEventTxt.write('TimeLimitInDay: ' + str(TimeLimitDay) + "\n")
                Writer_TouchEventTxt.write('PunishDur: ' + str(PunishDur) + "\n")
                Writer_TouchEventTxt.write('Iti: ' + str(Iti) + "\n")
                Writer_TouchEventTxt.write('LickDur: ' + str(LickDur) + "\n")
                Writer_TouchEventTxt.write('EvalCorrectNum: ' + str(EvalCorrectNum) + "\n")
                Writer_TouchEventTxt.write('NecCorrectNum: ' + str(NecCorrectNum) + "\n")
                Writer_TouchEventTxt.write('CorrectPos: ' + str(CorrectPosVar.get()) + "\n")
                Writer_TouchEventTxt.write('WaterCueType: ' + str(WaterCueType) + "\n")
                Writer_TouchEventTxt.write('PunishLight: ' + str(PunishWithLight) + "\n")
                Writer_TouchEventTxt.write('RewardRateOfCorrectPos: ' + str(RewardRateOfCorrectPos) + "\n")
                Writer_TouchEventTxt.write('RewardRateOfWrongPos: ' + str(RewardRateOfWrongPos) + "\n")
                Writer_TouchEventTxt.write('Seed: ' + str(Seed) + "\n")
                Writer_TouchEventTxt.write('AWS: ' + AwsOn + "\n")
                Writer_TouchEventTxt.write('AWS_Latency : ' + str(AWS_Latency) + "\n")
                Writer_TouchEventTxt.write('RecordFPS: ' + str(GetRecordFps()) + "\n")
                Writer_TouchEventTxt.write(GetRoiSensitivity() + "\n")
                Writer_TouchEventTxt.write(GetServoAngle() + "\n")

                Writer_TouchEventTxt.close()
                Writer_TouchEventCsv.close()
                EndLickRecording()

                SendMail(DeviceNameVar.get() + ' finished task ' + str(Task) + '. Correct:' + str(CorrectNum) + ' Wrong:' + str(WrongNum) + ' Touch/Reversal:' + str(TrialPerReversal) + '% Dur:' + str(round(Timer_GetSec(5) / 60, 1)) + ' min', 'The task is finished')


                if IsHousingAnalysis == 0:
                    RoofLightOn()
                Phase = 1  # Go back to the task-waiting phase
                Phase2 = 0
                Phase2_Init = 0

    return

def Task15():   # 5-choice serial-reaction time task (5-CSRTT)
    global Phase
    Phase0_Init=0
    Phase1_Init=0
    Phase2_Init=0
    while EndFlag==0:
        OperantHouseUpdate()
        if GetBackButtonStat()==1:    # If "Back" button is clicked
            break   # Back to the task select phase
        if Phase == 0:  # Parameter inputs
            if Phase0_Init == 0:
                # Make GUI for the setting of the parameters for this task
                RemoveMainRightWidget() # Remove task buttons
                PutStartBackButton()    # Put start/back buttons

                ColumnWidth = 11
                Row = 0  # Begin a new line
                Column = 0
                mMaxCorrectNum = ttk.Label(MainWindowRightFrame, text='MaxCorrect', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                MaxCorrectNumVar = IntVar(MainWindowRoot)  # Declare variable receiving value from the entry field
                iMaxCorrectNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxCorrectNumVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mMaxTrialNum = ttk.Label(MainWindowRightFrame, text='MaxTrial', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                MaxTrialNumVar = IntVar(MainWindowRoot)
                iMaxTrialNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxTrialNumVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mTimeLimit = ttk.Label(MainWindowRightFrame, text='Limit(min)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                TimeLimitVar = DoubleVar(MainWindowRoot)
                iTimeLimit = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mPunishDur = ttk.Label(MainWindowRightFrame, text='Punish(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                PunishDurVar = DoubleVar(MainWindowRoot)
                iPunishDur = ttk.Entry(MainWindowRightFrame, textvariable=PunishDurVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mLickDur = ttk.Label(MainWindowRightFrame, text='LickDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                LickDurVar = DoubleVar(MainWindowRoot)
                iLickDur = ttk.Entry(MainWindowRightFrame, textvariable=LickDurVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mTrialInit = ttk.Label(MainWindowRightFrame, text='TrialInit', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                TrialInitVar = StringVar(MainWindowRightFrame)
                tTrialInit = OptionMenu(MainWindowRightFrame, TrialInitVar, "ON", "OFF").grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mNextTaskTh = ttk.Label(MainWindowRightFrame, text='NextTaskTh%', width=14).grid(row=Row, column=Column, sticky=W)  # Put label
                NextTaskThVar = DoubleVar(MainWindowRoot)
                iNextTaskTh = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskThVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mNextTask = ttk.Label(MainWindowRightFrame, text='NextTask#', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                NextTaskVar = IntVar(MainWindowRoot)
                iNextTask = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label

                Row += 2  # Begin a new line
                Column = 0

                mIar = ttk.Label(MainWindowRightFrame, text='IAR(s)', width=11).grid(row=Row, column=Column, sticky=W)  # Put label
                IarVar = StringVar(MainWindowRoot)
                iIar = ttk.Entry(MainWindowRightFrame, textvariable=IarVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label

                Column += 1  # Shift column
                mIti0 = ttk.Label(MainWindowRightFrame, text='ITI 0(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                Iti0Var = StringVar(MainWindowRoot)
                iIti0 = ttk.Entry(MainWindowRightFrame, textvariable=Iti0Var, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mIti1 = ttk.Label(MainWindowRightFrame, text='ITI 1(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                Iti1Var = StringVar(MainWindowRoot)
                iIti1 = ttk.Entry(MainWindowRightFrame, textvariable=Iti1Var, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mIti2 = ttk.Label(MainWindowRightFrame, text='ITI 2(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                Iti2Var = StringVar(MainWindowRoot)
                iIti2 = ttk.Entry(MainWindowRightFrame, textvariable=Iti2Var, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mIti3 = ttk.Label(MainWindowRightFrame, text='ITI 3(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                Iti3Var = StringVar(MainWindowRoot)
                iIti3 = ttk.Entry(MainWindowRightFrame, textvariable=Iti3Var, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column

                mStimDur0 = ttk.Label(MainWindowRightFrame, text='StimDur0 s', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                StimDur0Var = StringVar(MainWindowRoot)
                iStimDur0 = ttk.Entry(MainWindowRightFrame, textvariable=StimDur0Var, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mStimDur1 = ttk.Label(MainWindowRightFrame, text='StimDur1 s', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                StimDur1Var = StringVar(MainWindowRoot)
                iStimDur1 = ttk.Entry(MainWindowRightFrame, textvariable=StimDur1Var, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mStimDur2 = ttk.Label(MainWindowRightFrame, text='StimDur2 s', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                StimDur2Var = StringVar(MainWindowRoot)
                iStimDur2 = ttk.Entry(MainWindowRightFrame, textvariable=StimDur2Var, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mStimDur3 = ttk.Label(MainWindowRightFrame, text='StimDur3 s', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                StimDur3Var = StringVar(MainWindowRoot)
                iStimDur3 = ttk.Entry(MainWindowRightFrame, textvariable=StimDur3Var, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column

                mLimitedHold = ttk.Label(MainWindowRightFrame, text='LimitedHold(s)', width=11).grid(row=Row, column=Column, sticky=W)  # Put label
                LimitedHoldVar = StringVar(MainWindowRoot)
                iLimitedHold = ttk.Entry(MainWindowRightFrame, textvariable=LimitedHoldVar, width=ColumnWidth).grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column

                Row += 2  # Begin a new line
                Column = 0

                mPanelType = ttk.Label(MainWindowRightFrame, text='PanelType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                PanelTypeVar = StringVar(MainWindowRightFrame)
                tPanelType = OptionMenu(MainWindowRightFrame, PanelTypeVar, "Normal", "Blink", "Textured").grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mWaterCueType = ttk.Label(MainWindowRightFrame, text='WaterCueType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                WaterCueTypeVar = StringVar(MainWindowRightFrame)
                tWaterCueType = OptionMenu(MainWindowRightFrame, WaterCueTypeVar, "Normal", "Blink").grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mPunishWithLight = ttk.Label(MainWindowRightFrame, text='PunishLight', width=11).grid(row=Row, column=Column, sticky=W)  # Put label
                PunishWithLightVar = StringVar(MainWindowRightFrame)
                tPunishWithLight = OptionMenu(MainWindowRightFrame, PunishWithLightVar, "ON", "OFF").grid(row=Row + 1, column=Column, sticky=W)  # Put label
                Column += 1  # Shift column
                mAwsOn = ttk.Label(MainWindowRightFrame, text='AWS', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Put label
                AwsOnVar = StringVar(MainWindowRoot)
                tAwsOn = OptionMenu(MainWindowRightFrame, AwsOnVar, "ON", "OFF").grid(row=Row + 1, column=Column, sticky=W)  # Put label

                Str = "ParametersForTask" + str(GetTaskID())
                if os.path.exists(Str + '/MaxCorrectNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxCorrectNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxCorrectNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxCorrectNumVar.set(80)  # Default value

                if os.path.exists(Str + '/MaxTrialNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxTrialNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxTrialNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxTrialNumVar.set(110)  # Default value

                if os.path.exists(Str + '/TimeLimit.dat') == True:  # If save file exists
                    with open(Str + '/TimeLimit.dat', 'rb') as PickleInst[GetTaskID()]:
                        TimeLimitVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    TimeLimitVar.set(360)  # Default value

                if os.path.exists(Str + '/PunishDur.dat') == True:  # If save file exists
                    with open(Str + '/PunishDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishDurVar.set(10)  # Default value

                if os.path.exists(Str + '/LickDur.dat') == True:  # If save file exists
                    with open(Str + '/LickDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        LickDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    LickDurVar.set(2)  # Default value

                if os.path.exists(Str + '/TrialInit.dat') == True:  # If save file exists
                    with open(Str + '/TrialInit.dat', 'rb') as PickleInst[GetTaskID()]:
                        TrialInitVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    TrialInitVar.set('ON')  # Default value

                if os.path.exists(Str + '/NextTaskTh.dat') == True:  # If save file exists
                    with open(Str + '/NextTaskTh.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskThVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskThVar.set(80)  # Default value

                if os.path.exists(Str + '/NextTask.dat') == True:  # If save file exists
                    with open(Str + '/NextTask.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskVar.set(15)  # Default value


                if os.path.exists(Str + '/Iar.dat') == True:  # If save file exists
                    with open(Str + '/Iar.dat', 'rb') as PickleInst[GetTaskID()]:
                        IarVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    IarVar.set('5')  # Default value

                if os.path.exists(Str + '/Iti0.dat') == True:  # If save file exists
                    with open(Str + '/Iti0.dat', 'rb') as PickleInst[GetTaskID()]:
                        Iti0Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Iti0Var.set('5')  # Default value

                if os.path.exists(Str + '/Iti1.dat') == True:  # If save file exists
                    with open(Str + '/Iti1.dat', 'rb') as PickleInst[GetTaskID()]:
                        Iti1Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Iti1Var.set('')  # Default value

                if os.path.exists(Str + '/Iti2.dat') == True:  # If save file exists
                    with open(Str + '/Iti2.dat', 'rb') as PickleInst[GetTaskID()]:
                        Iti2Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Iti2Var.set('')  # Default value

                if os.path.exists(Str + '/Iti3.dat') == True:  # If save file exists
                    with open(Str + '/Iti3.dat', 'rb') as PickleInst[GetTaskID()]:
                        Iti3Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    Iti3Var.set('')  # Default value

                if os.path.exists(Str + '/StimDur0.dat') == True:  # If save file exists
                    with open(Str + '/StimDur0.dat', 'rb') as PickleInst[GetTaskID()]:
                        StimDur0Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    StimDur0Var.set('16')  # Default value

                if os.path.exists(Str + '/StimDur1.dat') == True:  # If save file exists
                    with open(Str + '/StimDur1.dat', 'rb') as PickleInst[GetTaskID()]:
                        StimDur1Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    StimDur1Var.set('')  # Default value

                if os.path.exists(Str + '/StimDur2.dat') == True:  # If save file exists
                    with open(Str + '/StimDur2.dat', 'rb') as PickleInst[GetTaskID()]:
                        StimDur2Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    StimDur2Var.set('')  # Default value

                if os.path.exists(Str + '/StimDur3.dat') == True:  # If save file exists
                    with open(Str + '/StimDur3.dat', 'rb') as PickleInst[GetTaskID()]:
                        StimDur3Var.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    StimDur3Var.set('')  # Default value

                if os.path.exists(Str + '/LimitedHold.dat') == True:  # If save file exists
                    with open(Str + '/LimitedHold.dat', 'rb') as PickleInst[GetTaskID()]:
                        LimitedHoldVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    LimitedHoldVar.set('4')  # Default value


                if os.path.exists(Str + '/PanelType.dat') == True:  # If save file exists
                    with open(Str + '/PanelType.dat', 'rb') as PickleInst[GetTaskID()]:
                        PanelTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PanelTypeVar.set('Normal')  # Default value

                if os.path.exists(Str + '/WaterCueType.dat') == True:  # If save file exists
                    with open(Str + '/WaterCueType.dat', 'rb') as PickleInst[GetTaskID()]:
                        WaterCueTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    WaterCueTypeVar.set('Blink')  # Default value

                if os.path.exists(Str + '/PunishWithLight.dat') == True:  # If save file exists
                    with open(Str + '/PunishWithLight.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishWithLightVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PunishWithLightVar.set('ON')  # Default value

                if os.path.exists(Str + '/AwsOn.dat') == True:  # If save file exists
                    with open(Str + '/AwsOn.dat', 'rb') as PickleInst[GetTaskID()]:
                        AwsOnVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    AwsOnVar.set('ON')  # Default value


                RemoveAllRoiGui()
                for i in range(GetCurrentPanelNum()):
                    PutRoiGui(i, 1, 1, 0)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)  Set panel ROIs
                PutRoiGui(19, 0, 0, 1)  # (P1:ROI# P2:Detection mode P3:Th direction P4:ShowSymbol)  ROI 19 is water ROI

                RemoveAllDigitalOutGui()
                PutDigitalOutGui(10)  # Cue LED
                PutDigitalOutGui(12)  # IR LED
                PutDigitalOutGui(13)  # Roof LED

                RemoveAllServoGui()
                PutServoGui(3)

                Phase0_Init = 1

        if GetSaveTrgStat() == 1:    # If save trigger is on
            # Parameters of each task are saved into different folder
            Str="ParametersForTask"+str(GetTaskID())   # Path to the folder for saving of parameters
            if os.path.exists(Str) == False:    # If folder for saving parameters is not exist
                os.mkdir(Str)   # Make folder for saving
            with open(Str+'/MaxCorrectNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxCorrectNumVar.get(),PickleInst[GetTaskID()])     # Save
            with open(Str+'/MaxTrialNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxTrialNumVar.get(),PickleInst[GetTaskID()])     # Save
            with open(Str + '/TimeLimit.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TimeLimitVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str+'/PunishDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishDurVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/LickDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(LickDurVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/TrialInit.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TrialInitVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str + '/NextTask.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str+'/NextTaskTh.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskThVar.get(), PickleInst[GetTaskID()])     # Save

            with open(Str+'/Iar.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(IarVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/Iti0.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Iti0Var.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/Iti1.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Iti1Var.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/Iti2.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Iti2Var.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/Iti3.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(Iti3Var.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/StimDur0.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(StimDur0Var.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/StimDur1.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(StimDur1Var.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/StimDur2.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(StimDur2Var.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/StimDur3.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(StimDur3Var.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/LimitedHold.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(LimitedHoldVar.get(), PickleInst[GetTaskID()])     # Save

            with open(Str+'/PanelType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PanelTypeVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/WaterCueType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(WaterCueTypeVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/PunishWithLight.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishWithLightVar.get(), PickleInst[GetTaskID()])     # Save
            with open(Str+'/AwsOn.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(AwsOnVar.get(), PickleInst[GetTaskID()])     # Save

        if Phase == 1:  # Wait for starting of task
            if Phase1_Init == 0:
                PutPreTaskButton()
                mStatusVar = StringVar(MainWindowRoot)
                mStatus = ttk.Label(MainWindowRightFrame, textvariable=mStatusVar)
                mStatus.place(x=10, y=0)
                mOngoingResultVar = StringVar(MainWindowRoot)
                Phase1_Init = 1
            mStatusVar.set('Touch lit panel task (' + str(GetTaskID()) + ')    Waiting...')
            if IsStartTime() == 1:
                StartNow()
        if Phase == 2:  # During task
            if Phase2_Init == 0: # Initialization of the task
                PutEndTaskNowButton()
                mStatusVar.set('Touch lit panel task (' + str(GetTaskID()) + ')    Start time ' + str(TaskStartedMonth) + '/' + str(TaskStartedDay) + ' ' + str(TaskStartedHour) + ':' + str(TaskStartedMinute) + '    Running')
                mOngoingResult = ttk.Label(MainWindowRightFrame, textvariable=mOngoingResultVar)
                mOngoingResult.place(x=10, y=18)

                # Convert StringVars of parameters into integer or normal string to use in the following
                MaxCorrectNum=int(MaxCorrectNumVar.get())
                MaxTrialNum = int(MaxTrialNumVar.get())
                TimeLimit = float(TimeLimitVar.get())
                PunishDur = float(PunishDurVar.get())
                LickDur = float(LickDurVar.get())
                TrialInit = TrialInitVar.get()
                NextTask = int(NextTaskVar.get())
                NextTaskTh = float(NextTaskThVar.get())

                Iti = [-1.0]*4
                StimDur = [-1.0]*4
                ItiNum = 0
                StimDurNum = 0
                Temp =  MaxTrialNum+3
                ItiID = [-1] * Temp
                StimDurID = [-1] * Temp
                TempID = 0

                Iar = float(IarVar.get())
                if Iti0Var.get() != "":
                    Iti[0] = float(Iti0Var.get())
                if Iti1Var.get() != "":
                    Iti[1] = float(Iti1Var.get())
                if Iti2Var.get() != "":
                    Iti[2] = float(Iti2Var.get())
                if Iti3Var.get() != "":
                    Iti[3] = float(Iti3Var.get())
                if StimDur0Var.get() != "":
                    StimDur[0] = float(StimDur0Var.get())
                if StimDur1Var.get() != "":
                    StimDur[1] = float(StimDur1Var.get())
                if StimDur2Var.get() != "":
                    StimDur[2] = float(StimDur2Var.get())
                if StimDur3Var.get() != "":
                    StimDur[3] = float(StimDur3Var.get())
                LimitedHold = float(LimitedHoldVar.get())

                PanelType = PanelTypeVar.get()
                WaterCueType =WaterCueTypeVar.get()
                PunishWithLight = PunishWithLightVar.get()
                AwsOn = AwsOnVar.get()

                StartLickRecording()
                RoofLightOff()
                InfraredLightOn()
                if WaterCueType == 'Normal':
                    DigitalOutOn(10)
                if WaterCueType == 'Blink':
                    DigitalOutBlinkOn(10)
                ServoPosInside(3)
                if PanelType=='Normal':
                    CreateNormalPanel_All() #
                if PanelType=='Blink':
                    CreateBlinkPanel_All()
                if PanelType=='Textured':
                    CreateTexturedPanel_All(0)


                # Declar local variables for this task
                TotalTouchNum = 0
                CorrectNum = 0
                IncorrectNum = 0
                PrematureNum = 0
                OmissionNum = 0
                CorrectRate = 0.0
                PrematureRate = 0.0
                OmissionRate = 0.0
                TaskDur = 0

                CurrItiID = -1
                AWS_Latency = 20
                LightCycleControlOff()
                NowDrinking = 0
                CorrectPanelID = 0    # ID of correct panel
                TouchTimeWindow = 0
                IsPanelHidden = 0   # A trigger to hide the panel during stimulus display phase
                StartRecording()    # Start camera capturing and sending of TTL

                TrialNum=0
                Timer_Start(5)  # Task time limit timer start
                Phase2 = 5
                Phase2_Init = 1

                Writer_TouchEventTxt = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.txt",'w')  # Initialize the text exporter
                Writer_TouchEventCsv = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.csv",'w')  # Initialize the text exporter
                Writer_TouchEventTxt.write('TrialNum\tResult\t\t\tyyyy/mm/dd\th:m\ts\n')  # Write item name
                print("Task #" + str(GetTaskID()) + " is started at " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

                # Init of table of random numbers for ITI
                for i in range(4):
                    if Iti[i] != -1.0:  # Count the number of ITI in the task parameter
                        ItiNum += 1
                    if Iti[i] == -1.0:
                        break
                print("\nITI number is "+str(ItiNum))
                CurrID = 0
                CurrShift = 0
                for i in range(int(MaxTrialNum/ItiNum)+1):
                    for i2 in range(ItiNum):    # Within block
                        while True:
                            TempID = CurrShift + int(random.random() * ItiNum)
                            if ItiID[TempID] == -1: # If this list is not used yet
                                ItiID[TempID] = i2
                                CurrID += 1
                                break
                    CurrShift += ItiNum
                    if CurrID >= MaxTrialNum:
                        break
                print("Random ITIs are assigned as follows")
                #for i in range(len(ItiID)-3):
                #    print("Trial "+str(i)+": "+str(ItiID[i]))

                # Init of table of random numbers for StimDur
                for i in range(4):
                    if StimDur[i] != -1.0:  # Count the number of StimDur in the task parameter
                        StimDurNum += 1
                    if StimDur[i] == -1.0:
                        break
                print("\nStimDur number is " + str(StimDurNum))
                CurrID = 0
                CurrShift = 0
                for i in range(int(MaxTrialNum / StimDurNum) + 1):
                    for i2 in range(StimDurNum):
                        while True:
                            TempID = CurrShift + int(random.random() * StimDurNum)
                            if StimDurID[TempID] == -1:
                                StimDurID[TempID] = i2
                                CurrID += 1
                                break
                    CurrShift += StimDurNum
                    if CurrID >= MaxTrialNum:
                        break
                print("Random stimulus durations are assigned as follows")
                for i in range(len(StimDurID)-3):
                    print("Trial "+str(i)+": "+str(StimDurID[i]))


            if Phase2 == 0:   # Initiation of new trial
                TaskDur = Timer_GetSec(5)
                TrialNum += 1   #
                CurrItiID += 1
                if CurrItiID >= MaxTrialNum:
                    CurrItiID = 0
                if TrialInit == "ON":
                    if WaterCueType == 'Normal':
                        DigitalOutBlinkOn(10)
                    if WaterCueType == 'Blink':
                        DigitalOutOn(10)
                    Phase2 = 1
                if TrialInit == "OFF":  # Skip water slit nosepoke detection phase
                    Timer_Start(0)  # Start the latency timer
                    Phase2 = 2

            if Phase2 == 1:  # Trial trigger waiting phase
                TouchedPanelID = DetectRoiNosepoke()  # Examine which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID == 19:  # If water slit ROI detects nosepoking
                    DigitalOutOff(10)
                    print("Next ITI is " + str(Iti[ItiID[CurrItiID]]) + " sec")
                    Timer_Start(0)  # Start the latency timer
                    Phase2 = 2

            if Phase2 == 2:  # ITI phase
                TouchedPanelID = DetectRoiNosepoke()  # Examine which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID != -1 and TouchedPanelID != 19:  # If any panel is touched
                    HideAllPanel()
                    ServoPosOutside(3)
                    if PunishWithLight == 'ON':
                        RoofLightOn()  # Turn on roof light
                    PrematureNum += 1
                    TotalTouchNum += 1
                    if CorrectNum > 0 or IncorrectNum > 0:
                        CorrectRate = round(CorrectNum * 100.0 / (CorrectNum + IncorrectNum), 2)
                    if PrematureNum > 0 or CorrectNum > 0 or IncorrectNum > 0:
                        PrematureRate = round(PrematureNum * 100.0 / (PrematureNum + CorrectNum + IncorrectNum), 2)
                    if OmissionNum > 0 or CorrectNum > 0 or IncorrectNum > 0:
                        OmissionRate = round(OmissionNum * 100.0 / (OmissionNum + CorrectNum + IncorrectNum), 2)
                    mOngoingResultVar.set('Correct:' + str(CorrectNum) + '  Incorrect:' + str(IncorrectNum) + '  Premature:' + str(PrematureNum) + '  Omission:' + str(OmissionNum) + '  Correct:' + str(round(CorrectRate, 2))+"%" + '  Premature:' + str(round(PrematureRate, 2))+"%" + '  Omission:' + str(round(OmissionRate, 2))+"%")
                    Writer_TouchEventTxt.write(str(TrialNum) + '\tPrematureTouch\t' + str(TouchedPanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                    Writer_TouchEventCsv.write(str(TrialNum) + ',3,' + str(TouchedPanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                    Timer_End(0)  # End timer1
                    Timer_Start(0)  # Start punish timer
                    Phase2 = 6  # Start punishment phase

                if Timer_GetSec(0) >= Iti[ItiID[CurrItiID]]:  # If ITI is passed
                    Phase2 = 3 # Go to the stimulus presentation phase

            if Phase2 == 3:  # Stimulus presentation init phase
                print(GetCurrentPanelNum())
                CorrectPanelID = int(random.random() * GetCurrentPanelNum())
                print('CorrectPanelID: ' + str(CorrectPanelID))
                ShowPanel(CorrectPanelID)
                Timer_Start(0)  # A timer to measure the stimulus presentation time (Omission timer)
                IsPanelHidden = 0
                Phase2 = 4
            if Phase2 == 4:  # stimulus presentation phase (Waiting to touch the panel)
                TouchedPanelID = DetectRoiNosepoke()  # Examine which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID != -1 and TouchedPanelID != 19:  # If any panel is touched
                    if TouchedPanelID == int(CorrectPanelID): # If mouse touchs correct panel
                        HideAllPanel()
                        ServoPosInside(3)  # Move water nozzle to the inside position
                        Timer_End(0)
                        if WaterCueType == 'Normal':
                            DigitalOutOn(10)
                        if WaterCueType == 'Blink':
                            DigitalOutBlinkOn(10)
                        NowDrinking = 0
                        CorrectNum += 1  # Increase the number of correct respon
                        TotalTouchNum += 1
                        if CorrectNum > 0 or IncorrectNum > 0:
                            CorrectRate = round(CorrectNum * 100.0 / (CorrectNum + IncorrectNum), 2)
                        if PrematureNum > 0 or CorrectNum > 0 or IncorrectNum > 0:
                            PrematureRate = round(PrematureNum * 100.0 / (PrematureNum + CorrectNum + IncorrectNum), 2)
                        if OmissionNum > 0 or CorrectNum > 0 or IncorrectNum > 0:
                            OmissionRate = round(OmissionNum * 100.0 / (OmissionNum + CorrectNum + IncorrectNum), 2)
                        mOngoingResultVar.set('Correct:' + str(CorrectNum) + '  Incorrect:' + str(IncorrectNum) + '  Premature:' + str(PrematureNum) + '  Omission:' + str(OmissionNum) + '  Correct:' + str(round(CorrectRate, 2))+"%" + '  Premature:' + str(round(PrematureRate, 2))+"%" + '  Omission:' + str(round(OmissionRate, 2))+"%")
                        Writer_TouchEventTxt.write(str(TrialNum) + '\tCorrectTouch\t' + str(TouchedPanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',1,' + str(TouchedPanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                        Phase2 = 5  # Start reward phase

                    if TouchedPanelID != int(CorrectPanelID): # If mouse touchs wrong panel
                        HideAllPanel()
                        ServoPosOutside(3)
                        if PunishWithLight == 'ON':
                            RoofLightOn()  # Turn on roof light
                        IncorrectNum += 1
                        TotalTouchNum += 1
                        if CorrectNum > 0 or IncorrectNum > 0:
                            CorrectRate = round(CorrectNum * 100.0 / (CorrectNum + IncorrectNum), 2)
                        if PrematureNum > 0 or CorrectNum > 0 or IncorrectNum > 0:
                            PrematureRate = round(PrematureNum * 100.0 / (PrematureNum + CorrectNum + IncorrectNum), 2)
                        if OmissionNum > 0 or CorrectNum > 0 or IncorrectNum > 0:
                            OmissionRate = round(OmissionNum * 100.0 / (OmissionNum + CorrectNum + IncorrectNum), 2)
                        mOngoingResultVar.set('Correct:' + str(CorrectNum) + '  Incorrect:' + str(IncorrectNum) + '  Premature:' + str(PrematureNum) + '  Omission:' + str(OmissionNum) + '  Correct:' + str(round(CorrectRate, 2))+"%" + '  Premature:' + str(round(PrematureRate, 2))+"%" + '  Omission:' + str(round(OmissionRate, 2))+"%")
                        Writer_TouchEventTxt.write(str(TrialNum) + '\tIncorrectTouch\t' + str(TouchedPanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',0,' + str(TouchedPanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                        Timer_End(0)  # End timer1
                        Timer_Start(0)  # Start punish timer
                        Phase2 = 6  # Start punishment phase

                if Timer_GetSec(0) >= StimDur[StimDurID[CurrItiID]] and IsPanelHidden == 0:
                    HidePanel(CorrectPanelID)
                    IsPanelHidden = 1

                    # Calculate TouchTimeWindow
                if StimDur[StimDurID[CurrItiID]] > LimitedHold:
                    TouchTimeWindow = StimDur[StimDurID[CurrItiID]]
                if StimDur[StimDurID[CurrItiID]] <= LimitedHold:
                    TouchTimeWindow = LimitedHold
                if Timer_GetSec(0) >= TouchTimeWindow:   # If Omission (the stimulus duration has elapsed)
                    Timer_End(0)  # End timer1
                    HideAllPanel()
                    OmissionNum += 1
                    if CorrectNum > 0 or IncorrectNum > 0:
                        CorrectRate = round(CorrectNum * 100.0 / (CorrectNum + IncorrectNum), 2)
                    if PrematureNum > 0 or CorrectNum > 0 or IncorrectNum > 0:
                        PrematureRate = round(PrematureNum * 100.0 / (PrematureNum + CorrectNum + IncorrectNum), 2)
                    if OmissionNum > 0 or CorrectNum > 0 or IncorrectNum > 0:
                        OmissionRate = round(OmissionNum * 100.0 / (OmissionNum + CorrectNum + IncorrectNum), 2)
                    mOngoingResultVar.set('Correct:' + str(CorrectNum) + '  Incorrect:' + str(IncorrectNum) + '  Premature:' + str(PrematureNum) + '  Omission:' + str(OmissionNum) + '  Correct:' + str(round(CorrectRate, 2))+"%" + '  Premature:' + str(round(PrematureRate, 2))+"%" + '  Omission:' + str(round(OmissionRate, 2))+"%")
                    Writer_TouchEventTxt.write(str(TrialNum) + '\tStimOmission\t' + str(TouchedPanelID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                    Writer_TouchEventCsv.write(str(TrialNum) + ',2,' + str(TouchedPanelID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                    Timer_Start(0)  # Start punish timer
                    Phase2 = 6  #

                if Timer_GetSec(5) >= TimeLimit * 60:   # If time limit is exceeded
                    TaskDur = Timer_GetSec(5)
                    Timer_End(5)
                    ServoPosMiddle(3)
                    DigitalOutOff(10)
                    Timer_Start(0)  # Timer for interval between task and arbitary water supply is started
                    Phase2 = 9

            if Phase2 == 5:  # Reward phase
                if DetectRoiNosepoke() == 19 and NowDrinking == 0:    # If the mouse initiates nose poke
                    NowDrinking = 1
                    Timer_Start(0)  # Start lick timer
                if NowDrinking == 1:
                    if Timer_GetSec(0) >= LickDur:   # If lick time exceed the designated time
                        Timer_End(0) # End lick timer
                        ServoPosMiddle(3)    # Move water nozzle to the intermediate position
                        DigitalOutOff(10)
                        NowDrinking = 0
                        Timer_Start(0)  # Start ITI timer
                        Phase2 = 7

            if Phase2 == 6:   # Punishment phase
                if Timer_GetSec(0) >= PunishDur:    # If punishment time is passed
                    RoofLightOff()
                    ServoPosMiddle(3)    # Move water nozzle to the intermediate position
                    Timer_End(0)  # End punishment timer1
                    Timer_Start(0)  # Start ITI timer
                    Phase2 = 8

            if Phase2 == 7:  # Interval after reward (Iar)
                if Timer_GetSec(0) >= Iar:  # If Iar has been passed
                    Timer_End(0)  # End punishment timer1
                    Phase2 = 8

            if Phase2 == 8:   # Trial end processing
                Phase2 = 0  # Go to the next trial
                #if CorrectNum >= MaxCorrectNum or TotalTouchNum >= MaxTrialNum: # If mouse achieved criteria of finishing the task
                if CorrectNum >= MaxCorrectNum or TrialNum >= MaxTrialNum:  # If mouse achieved criteria of finishing the task
                    Timer_End(5)
                    ServoPosMiddle(3)
                    DigitalOutOff(10)
                    Timer_Start(0)  # Timer for interval between task and arbitary water supply is started
                    Phase2 = 9  # Go to the AWS check

            if Phase2==9:   # Determines to start AWS or not
                HideAllPanel()
                if CorrectNum < MaxCorrectNum and AwsOn=='ON':  # If mouse didn't achieved the max correct response
                    Timer_Start(0)
                    Phase2 = 10
                if CorrectNum == MaxCorrectNum or AwsOn=='OFF':  # If mouse achieved the max correct response
                    Phase2 = -1

            if Phase2==10:   # Wait until arbitary water suuply (AWS) is started
                if Timer_GetSec(0) >= AWS_Latency:   # If the interval is past 60
                    Timer_End(0)
                    ArbitaryWaterSupplyDur=(MaxCorrectNum - CorrectNum) * LickDur * 1000    # Caliculate duration of complement water supply
                    if WaterCueType == 'Normal':
                        StartArbitaryWaterSupply(3,10,0,ArbitaryWaterSupplyDur) # Start complement water supply
                    if WaterCueType == 'Blink':
                        StartArbitaryWaterSupply(3,10,1,ArbitaryWaterSupplyDur) # Start complement water supply
                    print("AWSstart")
                    Phase2=11

            if Phase2==11:
                if GetArbitaryWaterSupplyStat()==1: # If complement water supply is finished
                    Phase2 = -1

            if Phase2 == -1 or GetEndTaskNowButtonStat() == 1:  # Task finish phase
                LightCycleControlOn()
                ServoPosMiddle(3)
                DeleteAllPanel()
                InfraredLightOff()
                if GetRecordingStat() == 1:
                    SetEndRecordingTimer(60)
                if CorrectNum > 0 or IncorrectNum > 0:
                    CorrectRate = round(CorrectNum * 100.0 / (CorrectNum + IncorrectNum), 2)
                if PrematureNum > 0 or CorrectNum > 0 or IncorrectNum > 0:
                    PrematureRate = round(PrematureNum * 100.0 / (PrematureNum + CorrectNum + IncorrectNum), 2)
                if OmissionNum > 0 or CorrectNum > 0 or IncorrectNum > 0:
                    OmissionRate = round(OmissionNum * 100.0 / (OmissionNum + CorrectNum + IncorrectNum), 2)
                Writer_TouchEventTxt.write('Correct:' + str(CorrectNum) + ' Incorrect:' + str(IncorrectNum) + ' Premature:' + str(PrematureNum) + '  Omission:' + str(OmissionNum) + ' Correct:' + str(round(CorrectRate, 2)) + "%" + ' Premature:' + str(round(PrematureRate, 2)) + "%" + ' Omission:' + str(round(OmissionRate, 2)) + "%"+'\n')   #結果テキストの一番最後に成績のまとめを記入
                Writer_TouchEventTxt.write('SessionStartTime: ' + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()) + "\n")
                Writer_TouchEventTxt.write('SessionEndTime: ' + str(TimeNow.month) + '/' + str(TimeNow.day) + ' ' + str(TimeNow.hour) + ':' + str(TimeNow.minute) + ':' + str(TimeNow.second + (TimeNow.microsecond // 1000) / 1000) + "\n")
                Writer_TouchEventTxt.write('TaskDuration(sec): ' + str(TaskDur) + "\n")
                Writer_TouchEventTxt.write('MaxCorrectNum: '+str(MaxCorrectNum)+"\n")
                Writer_TouchEventTxt.write('MaxTrialNum: ' + str(MaxTrialNum) + "\n")
                Writer_TouchEventTxt.write('TimeLimit: ' + str(TimeLimit) + "\n")
                Writer_TouchEventTxt.write('PunishDur: ' + str(PunishDur) + "\n")
                Writer_TouchEventTxt.write('LickDur: ' + str(LickDur) + "\n")
                Writer_TouchEventTxt.write('TrialInit: ' + TrialInit + "\n")
                Writer_TouchEventTxt.write('NextTask: ' + str(NextTask) + "\n")
                Writer_TouchEventTxt.write('NextTaskTh: ' + str(NextTaskTh)+"\n")

                Writer_TouchEventTxt.write('Interval after reward: ' + str(Iar) + "\n")
                Writer_TouchEventTxt.write('ITI 0: ' + str(Iti[0]) + "\n")
                Writer_TouchEventTxt.write('ITI 1: ' + str(Iti[1]) + "\n")
                Writer_TouchEventTxt.write('ITI 2: ' + str(Iti[2]) + "\n")
                Writer_TouchEventTxt.write('ITI 3: ' + str(Iti[3]) + "\n")
                Writer_TouchEventTxt.write('StimDur0: ' + str(StimDur[0]) + "\n")
                Writer_TouchEventTxt.write('StimDur1: ' + str(StimDur[1]) + "\n")
                Writer_TouchEventTxt.write('StimDur2: ' + str(StimDur[2]) + "\n")
                Writer_TouchEventTxt.write('StimDur3: ' + str(StimDur[3]) + "\n")
                Writer_TouchEventTxt.write('LimitedHold: ' + str(LimitedHold) + "\n")

                Writer_TouchEventTxt.write('PanelType: ' + str(PanelType) + "\n")
                Writer_TouchEventTxt.write('WaterCueType: ' + str(WaterCueType) + "\n")
                Writer_TouchEventTxt.write('PunishLight: ' + str(PunishWithLight)+"\n")
                Writer_TouchEventTxt.write('RecordFPS: ' + str(GetRecordFps()) + "\n")
                Writer_TouchEventTxt.write('AWS: ' + AwsOn + "\n")
                Writer_TouchEventTxt.write('AWS_Latency: ' + str(AWS_Latency) + "\n")
                Writer_TouchEventTxt.write(GetRoiSensitivity() + "\n")
                Writer_TouchEventTxt.write(GetServoAngle() + "\n")
                Writer_TouchEventTxt.close()
                Writer_TouchEventCsv.close()
                EndLickRecording()

                SendMail(DeviceNameVar.get() + ' finished task '+str(GetTaskID())+'. Correct:' + str(CorrectNum) + ' Incorrect:' + str(IncorrectNum) + ' Premature:' + str(PrematureNum) + ' Omission:' + str(OmissionNum)+' Dur:' + str(round(Timer_GetSec(5) / 60,1)) + ' min', 'The task is finished.')

                if IsHousingAnalysis == 1 and Phase2 == -1:  # If it is housing analysis
                    if CorrectRate >= NextTaskTh:   # If the score exceed the criteria to switch the next task
                        SwitchTask(NextTask) # Onset task switch trigger
                        print("Task is switched to task#"+str(NextTask)+"  "+str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

                if IsHousingAnalysis == 0:
                    RoofLightOn()
                Phase = 1  # Go back to the task-waiting phase
                Phase2 = 0
                Phase2_Init = 0
            SetDispVariable(0, 'Phase2', str(Phase2))  # Display "Phase2" value on the main window
    return

def Task16():  # Simple lever conditioning task
    global Phase
    Phase0_Init = 0
    Phase1_Init = 0
    Phase2_Init = 0
    while EndFlag == 0:
        OperantHouseUpdate()
        if GetBackButtonStat() == 1:  # If "Back" button is clicked
            break  # Back to the task select phase
        if Phase == 0:  # Parameter inputs phase
            if Phase0_Init == 0:
                # Make GUI for the setting of the parameters for this task
                RemoveMainRightWidget()  # Remove task buttons on the main window
                PutStartBackButton()  # Put start/back buttons on the main window

                ColumnWidth = 14    # Width of each column
                Row = 0  # Begin a new line
                Column = 0
                mMaxTrialNum = ttk.Label(MainWindowRightFrame, text='MaxTrialNum', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                MaxTrialNumVar = IntVar(MainWindowRoot) # Create a new variable for input column
                iMaxTrialNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxTrialNumVar, width=ColumnWidth).grid(row=Row+1, column=Column)   # Create input column and link it with the variable
                Column += 1  # Shift column
                mTimeLimit = ttk.Label(MainWindowRightFrame, text='TimeLimit(min)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                TimeLimitVar = DoubleVar(MainWindowRoot)
                iTimeLimit = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitVar, width=ColumnWidth).grid(row=Row+1, column=Column)
                Column += 1  # Shift column
                mReqTouchNum = ttk.Label(MainWindowRightFrame, text='ReqTouchNum', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                ReqTouchNumVar = IntVar(MainWindowRoot)
                iReqTouchNum = ttk.Entry(MainWindowRightFrame, textvariable=ReqTouchNumVar, width=ColumnWidth).grid(row=Row+1, column=Column)
                Column += 1  # Shift column

                mMinIPI = ttk.Label(MainWindowRightFrame, text='Min IPI(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                MinIPIVar = DoubleVar(MainWindowRoot)
                iMinIPI = ttk.Entry(MainWindowRightFrame, textvariable=MinIPIVar, width=ColumnWidth).grid(row=Row + 1, column=Column)
                Column += 1  # Shift column

                mMaxIPI = ttk.Label(MainWindowRightFrame, text='MaxIPI(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                MaxIPIVar = DoubleVar(MainWindowRoot)
                iMaxIPI = ttk.Entry(MainWindowRightFrame, textvariable=MaxIPIVar, width=ColumnWidth).grid(row=Row + 1, column=Column)
                Column += 1  # Shift column

                mIti = ttk.Label(MainWindowRightFrame, text='ITI(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                ItiVar = DoubleVar(MainWindowRoot)
                iIti = ttk.Entry(MainWindowRightFrame, textvariable=ItiVar, width=ColumnWidth).grid(row=Row+1, column=Column)
                Column += 1  # Shift column
                mLickDur = ttk.Label(MainWindowRightFrame, text='LickDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                LickDurVar = DoubleVar(MainWindowRoot)
                iLickDur = ttk.Entry(MainWindowRightFrame, textvariable=LickDurVar, width=ColumnWidth).grid(row=Row+1, column=Column)
                Column += 1  # Shift column
                mWaterCueType = ttk.Label(MainWindowRightFrame, text='WaterCueType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                WaterCueTypeVar = StringVar(MainWindowRightFrame)
                tWaterCueType = OptionMenu(MainWindowRightFrame, WaterCueTypeVar, "Normal", "Blink").grid(row=Row+1, column=Column)
                Column += 1  # Shift column
                mUsedLever = ttk.Label(MainWindowRightFrame, text='UsedLever', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                UsedLeverVar = StringVar(MainWindowRightFrame)
                tUsedLever = OptionMenu(MainWindowRightFrame, UsedLeverVar, "Left", "Right", "Both").grid(row=Row + 1, column=Column)
                Row += 2  # Begin a new line
                Column = 0
                mNextTaskTh = ttk.Label(MainWindowRightFrame, text='NextTaskTh', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                NextTaskThVar = StringVar(MainWindowRightFrame)
                tNextTaskTh = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskThVar, width=ColumnWidth).grid(row=Row+1, column=Column)
                Column += 1  # Shift column
                mNextTask = ttk.Label(MainWindowRightFrame, text='NextTask', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                NextTaskVar = StringVar(MainWindowRightFrame)
                tNextTask = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskVar, width=ColumnWidth).grid(row=Row+1, column=Column)
                Column += 1  # Shift column
                mAwsOn = ttk.Label(MainWindowRightFrame, text='AwsOn', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                AwsOnVar = StringVar(MainWindowRightFrame)
                tAwsOn = OptionMenu(MainWindowRightFrame, AwsOnVar, "ON", "OFF").grid(row=Row + 1, column=Column)

                Str = "ParametersForTask" + str(GetTaskID())

                if os.path.exists(Str + '/MaxTrialNum.dat') == True:  # If save file exists
                    with open(Str + '/MaxTrialNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxTrialNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxTrialNumVar.set(80)  # Default value

                if os.path.exists(Str + '/TimeLimit.dat') == True:  # If save file exists
                    with open(Str + '/TimeLimit.dat', 'rb') as PickleInst[GetTaskID()]:
                        TimeLimitVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    TimeLimitVar.set(360)  # Default value

                if os.path.exists(Str + '/ReqTouchNum.dat') == True:  # If save file exists
                    with open(Str + '/ReqTouchNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        ReqTouchNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    ReqTouchNumVar.set(1)  # Default value

                if os.path.exists(Str + '/MinIPI.dat') == True:  # If save file exists
                    with open(Str + '/MinIPI.dat', 'rb') as PickleInst[GetTaskID()]:
                        MinIPIVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MinIPIVar.set(0)  # Default value

                if os.path.exists(Str + '/MaxIPI.dat') == True:  # If save file exists
                    with open(Str + '/MaxIPI.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxIPIVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    MaxIPIVar.set(0)  # Default value

                if os.path.exists(Str + '/Iti.dat') == True:  # If save file exists
                    with open(Str + '/Iti.dat', 'rb') as PickleInst[GetTaskID()]:
                        ItiVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    ItiVar.set(1)  # Default value
                if os.path.exists(Str + '/LickDur.dat') == True:  # If save file exists
                    with open(Str + '/LickDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        LickDurVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    LickDurVar.set(2)  # Default value

                if os.path.exists(Str + '/WaterCueType.dat') == True:  # If save file exists
                    with open(Str + '/WaterCueType.dat', 'rb') as PickleInst[GetTaskID()]:
                        WaterCueTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    WaterCueTypeVar.set('Blink')  # Default value

                if os.path.exists(Str + '/UsedLever.dat') == True:  # If save file exists
                    with open(Str + '/UsedLever.dat', 'rb') as PickleInst[GetTaskID()]:
                        UsedLeverVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    UsedLeverVar.set('Both')  # Default value

                if os.path.exists(Str + '/NextTaskTh.dat') == True:  # If save file exists
                    with open(Str + '/NextTaskTh.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskThVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskThVar.set(999)  # Default value

                if os.path.exists(Str + '/NextTask.dat') == True:  # If save file exists
                    with open(Str + '/NextTask.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskVar.set(16)  # Default value

                if os.path.exists(Str + '/AwsOn.dat') == True:  # If save file exists
                    with open(Str + '/AwsOn.dat', 'rb') as PickleInst[GetTaskID()]:
                        AwsOnVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    AwsOnVar.set('OFF')  # Default value

                RemoveAllRoiGui()
                PutRoiGui(19, 0, 0, 1)  # (ROI number, Detection mode, Threshold direction, ShowSymbol or not)

                RemoveAllDigitalOutGui()    # Remove all GUIs on the Digital out window
                PutDigitalOutGui(10)    # Put digital out GUI for the indicated channel on the Digital out window
                PutDigitalOutGui(12)
                PutDigitalOutGui(13)

                DigitalInOn(7)  # Activate the indicated channel for Digital input
                DigitalInOn(8)

                RemoveAllServoGui() # Remove all servo GUI in the Servo window
                PutServoGui(3)  # Put a servo GUI for the indicated channel on Servo window
                PutServoGui(5)
                PutServoGui(6)

                Phase0_Init = 1 # Flag to end initialization of phse0

        if GetSaveTrgStat() == 1:  # If save trigger is on
            # Parameters of each task are saved into different folder
            Str = "ParametersForTask" + str(GetTaskID())  # Path to the folder for saving of parameters
            if os.path.exists(Str) == False:  # If folder for saving parameters is not exist
                os.mkdir(Str)  # Make folder for saving
            with open(Str + '/MaxTrialNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxTrialNumVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/TimeLimit.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TimeLimitVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/ReqTouchNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(ReqTouchNumVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/MinIPI.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MinIPIVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/MaxIPI.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxIPIVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/Iti.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(ItiVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/LickDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(LickDurVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/WaterCueType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(WaterCueTypeVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/UsedLever.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(UsedLeverVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/NextTaskTh.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskThVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/NextTask.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskVar.get(), PickleInst[GetTaskID()])  # Save
            with open(Str + '/AwsOn.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(AwsOnVar.get(), PickleInst[GetTaskID()])  # Save

        if Phase == 1:  # Wait for starting of task
            if Phase1_Init == 0:
                PutPreTaskButton()
                mStatusVar = StringVar(MainWindowRoot)
                mStatus = ttk.Label(MainWindowRightFrame, textvariable=mStatusVar)
                mStatus.place(x=10, y=0)
                mOngoingResultVar = StringVar(MainWindowRoot)
                Phase1_Init = 1
            mStatusVar.set('Lever conditioning task (' + str(GetTaskID()) + ')    Waiting...')
            if IsStartTime() == 1:
                StartNow()
        if Phase == 2:  # During task
            if Phase2_Init == 0:  # Initialization of the task
                PutEndTaskNowButton()

                mStatusVar.set('Lever conditioning task (' + str(GetTaskID()) + ')    Start time ' + str(TaskStartedMonth) + '/' + str(TaskStartedDay) + ' ' + str(TaskStartedHour) + ':' + str(
                    TaskStartedMinute) + '    Running')
                mOngoingResult = ttk.Label(MainWindowRightFrame, textvariable=mOngoingResultVar)
                mOngoingResult.place(x=10, y=18)

                # Convert StringVars of parameters into integer or normal string to use in the following
                MaxTrialNum = int(MaxTrialNumVar.get())
                TimeLimit = float(TimeLimitVar.get())
                Iti = float(ItiVar.get())
                LickDur = float(LickDurVar.get())
                WaterCueType = WaterCueTypeVar.get()
                UsedLever = UsedLeverVar.get()
                ReqTouchNum = int(ReqTouchNumVar.get())
                MinIPI = float(MinIPIVar.get())
                MaxIPI = float(MaxIPIVar.get())
                NextTaskTh = float(NextTaskThVar.get())
                NextTask = int(NextTaskVar.get())
                AwsOn = AwsOnVar.get()

                StartLickRecording()
                RoofLightOn()
                InfraredLightOn()

                ServoPosInside(3)
                if UsedLever == "Left":
                    ServoPosInside(5)
                    ServoPosMiddle(6)
                if UsedLever == "Right":
                    ServoPosInside(6)
                    ServoPosMiddle(5)
                if UsedLever == "Both":
                    ServoPosInside(5)
                    ServoPosInside(6)

                if WaterCueType == 'Normal':
                    DigitalOutOn(10)
                if WaterCueType == 'Blink':
                    DigitalOutBlinkOn(10)

                # Declar local variables for this task
                TouchNumInTrial=0
                TouchTrg=0
                TrialNum=0
                TaskDur = 0
                LeftLeverStat=-1
                RightLeverStat = -1
                PressedLeverID=-1


                LightCycleControlOff()
                DoneCorrectResponse=1
                NowDrinking = 0
                AWS_Latency = 20
                StartRecording()  # Start camera capturing and sending of TTL


                Timer_Start(5)  # Task time limit timer start tagg
                Phase2 = 2
                Phase2_Init = 1

                Writer_TouchEventTxt = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(
                    GetTaskID()) + " Touch.txt", 'w')  # Initialize the text exporter
                Writer_TouchEventCsv = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(
                    GetTaskID()) + " Touch.csv", 'w')  # Initialize the text exporter
                Writer_TouchEventTxt.write('TrialNum\tResult\t\t\tyyyy/mm/dd\th:m\ts\n')  # Write item name
                print("Task #" + str(GetTaskID()) + " is started at " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(
                    GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))


            if Phase2 == 0:  # Initiation of new trial
                TaskDur = Timer_GetSec(5)
                DoneCorrectResponse = 0
                TouchNumInTrial = 0
                TouchTrg = 0
                Timer_Start(0)  # Start the latency timer
                Phase2 += 1
            if Phase2 == 1:  # Panel presentation
                LeftLeverStat = DetectLeverPress(7)
                RightLeverStat = DetectLeverPress(8)
                if LeftLeverStat==1:
                    PressedLeverID=7
                if RightLeverStat==1:
                    PressedLeverID=8

                if LeftLeverStat==-1 and RightLeverStat==-1:
                    TouchTrg = 0
                if TouchTrg == 0:
                    if UsedLever=="Left" and LeftLeverStat==1 or UsedLever=="Right" and RightLeverStat==1 or UsedLever=="Both" and LeftLeverStat==1 or UsedLever=="Both" and RightLeverStat==1:
                        if Timer_GetSec(1) >= MinIPI and Timer_GetSec(1) <= MaxIPI or MaxIPI == 0 or TouchNumInTrial==0:   # If this press is the first one or occured within appropriate timing
                            TouchNumInTrial += 1

                        if Timer_GetSec(1) > MaxIPI and MaxIPI != 0: # If this press is followed after the time window
                            TouchNumInTrial = 1
                        if MinIPI!=0 or MaxIPI!=0:
                            print("IPI: "+str(Timer_GetSec(1))+"sec    Press# "+str(TouchNumInTrial))
                        if TouchNumInTrial < ReqTouchNum:
                            Writer_TouchEventTxt.write(str(TrialNum) + '\tLeverPress\t' + str(PressedLeverID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                            Writer_TouchEventCsv.write(str(TrialNum) + ',1,' + str(PressedLeverID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                        Timer_Start(1)
                        TouchTrg =1
                if TouchNumInTrial >= ReqTouchNum:
                    TrialNum += 1
                    ServoPosInside(3)  # Move water nozzle to the intermediate position
                    DoneCorrectResponse = 1
                    NowDrinking = 0
                    mOngoingResultVar.set('TouchNum:' + str(TrialNum))
                    Writer_TouchEventTxt.write(str(TrialNum) + '\tRewardedLeverPress\t' + str(PressedLeverID) + '\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                    Writer_TouchEventCsv.write(str(TrialNum) + ',2,' + str(PressedLeverID) + ',' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file

                    Timer_End(0)
                    Timer_Reset(1)
                    if WaterCueType=='Normal':
                        DigitalOutOn(10)
                    if WaterCueType == 'Blink':
                        DigitalOutBlinkOn(10)
                    Phase2 = 2  # Start reward phase
                if Timer_GetSec(5) >= TimeLimit * 60:  # If time limit is exceeded
                    TaskDur = Timer_GetSec(5)
                    Timer_End(5)
                    ServoPosInside(3)
                    ServoPosMiddle(5)
                    Phase2 = 6

            if Phase2 == 2:  # Reward phase
                if NowDrinking == 0:
                    if DetectRoiNosepoke() == 19 :  # If left lever press is detected
                        NowDrinking = 1
                        Timer_Start(0)  # Start lick timer
                if NowDrinking == 1:
                    if DoneCorrectResponse == 1 and Timer_GetSec(0) >= LickDur:  # If lick time exceed the designated time
                        Timer_End(0)  # End lick timer
                        ServoPosMiddle(3)  # Move water nozzle to the intermediate position
                        DigitalOutOff(10)
                        NowDrinking = 0
                        Timer_Start(0)  # Start ITI timer
                        Phase2 = 3

            if Phase2 == 3:  # ITI
                if Timer_GetSec(0) >= Iti:  # If ITI is passed
                    Timer_End(0)
                    Phase2 = 0  # Go to the next trial
                if TrialNum >= MaxTrialNum:  # If mouse achieved criteria of finishing the task
                    Timer_End(0)
                    Timer_Start(0)  # Timer for interval between task and arbitary water supply is started
                    Phase2 = 6  # End task

            if Phase2 == 6:
                if TrialNum < MaxTrialNum and AwsOn == 'ON':  # If mouse didn't achieved the max correct response
                    Timer_Start(0)
                    Phase2 = 7
                if TrialNum == MaxTrialNum or AwsOn == 'OFF':  # If mouse achieved the max correct response
                    Phase2 = -1

            if Phase2 == 7:  # Wait until arbitary water suuply is started
                if Timer_GetSec(0) >= AWS_Latency:  # If the interval is past 60
                    Timer_End(0)
                    ArbitaryWaterSupplyDur = (MaxTrialNum - TrialNum) * LickDur * 1000  # Caliculate duration of complement water supply
                    if WaterCueType == 'Normal':
                        StartArbitaryWaterSupply(3,10,0,ArbitaryWaterSupplyDur) # Start complement water supply
                    if WaterCueType == 'Blink':
                        StartArbitaryWaterSupply(3,10,1,ArbitaryWaterSupplyDur) # Start complement water supply
                    print("AWSstart")
                    Phase2 = 8
            if Phase2 == 8:
                if GetArbitaryWaterSupplyStat() == 1:  # If complement water supply is finished
                    Phase2 = -1



            if Phase2 == -1 or GetEndTaskNowButtonStat() == 1:  # Task finish phase
                LightCycleControlOn()
                DigitalOutOff(10)
                ServoPosMiddle(3)
                ServoPosMiddle(5)
                ServoPosMiddle(6)
                DeleteAllPanel()
                InfraredLightOff()
                #DigitalInOff(7)
                #DigitalInOff(8)
                if GetRecordingStat() == 1:
                    SetEndRecordingTimer(60)
                    Writer_TouchEventTxt.write('Touch# :' + str(TrialNum)+ "\n")  # 結果テキストの一番最後に成績のまとめを記入
                Writer_TouchEventTxt.write('SessionStartTime: ' + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()) + "\n")
                Writer_TouchEventTxt.write('SessionEndTime: ' + str(TimeNow.month) + '/' + str(TimeNow.day) + ' ' + str(TimeNow.hour) + ':' + str(TimeNow.minute) + ':' + str(TimeNow.second + (TimeNow.microsecond // 1000) / 1000) + "\n")
                Writer_TouchEventTxt.write('TaskDuration(sec): ' + str(TaskDur) + "\n")
                Writer_TouchEventTxt.write('MaxTrialNum: ' + str(MaxTrialNum) + "\n")
                Writer_TouchEventTxt.write('TimeLimit: ' + str(TimeLimit) + "\n")
                Writer_TouchEventTxt.write('ReqTouchNum: ' + str(ReqTouchNum) + "\n")
                Writer_TouchEventTxt.write('MinIPI: ' + str(MinIPI) + "\n")
                Writer_TouchEventTxt.write('MaxIPI: ' + str(MaxIPI) + "\n")
                Writer_TouchEventTxt.write('Iti: ' + str(Iti) + "\n")
                Writer_TouchEventTxt.write('LickDur: ' + str(LickDur) + "\n")
                Writer_TouchEventTxt.write('WaterCueType: ' + str(WaterCueType) + "\n")
                Writer_TouchEventTxt.write('UsedLever: ' + str(UsedLever) + "\n")
                Writer_TouchEventTxt.write('RecordFPS: ' + str(GetRecordFps()) + "\n")
                Writer_TouchEventTxt.write(GetRoiSensitivity() + "\n")
                Writer_TouchEventTxt.write(GetServoAngle() + "\n")

                Writer_TouchEventTxt.close()
                Writer_TouchEventCsv.close()
                EndLickRecording()
                SendMail(DeviceNameVar.get() + ' finished task ' + str(GetTaskID()) + '.  Dur:' + str(round(Timer_GetSec(5) / 60, 1)) + ' min', 'The task is finished.')


                if IsHousingAnalysis == 1 and Phase2 == -1:  # If it is housing analysis
                    RoofLightOff()
                if IsHousingAnalysis == 0:
                    RoofLightOn()
                Phase = 1  # Go back to the task-waiting phase
                Phase2 = 0
                Phase2_Init = 0

            SetDispVariable(0, 'Phase2', str(Phase2))  # Display "Phase2" value on the main window
    return


def Task89():   # Linear track
    global Phase
    Phase0_Init = 0
    Phase1_Init = 0
    Phase2_Init = 0
    while EndFlag == 0:
        OperantHouseUpdate()    # Run house keeping function (This must be executed once per frame)

        if GetBackButtonStat()==1:    # If "Back" button is clicked
            break   # Back to the task select phase
        if Phase == 0:  # Parameter inputs
            if Phase0_Init == 0:    # Make GUI for the setting of the parameters for this task
                RemoveMainRightWidget() # Remove task buttons
                PutStartBackButton()    # Put "start" and "back" buttons

                ColumnWidth = 14    # Width of input columns
                Row = 0
                Column = 0
                mMaxTrialNum = ttk.Label(MainWindowRightFrame, text='MaxTrialNum', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                MaxTrialNumVar = IntVar(MainWindowRoot)  # Declare a variable for input column
                iMaxTrialNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxTrialNumVar, width=ColumnWidth).grid(row=Row + 1, column=Column)
                Column += 1
                mTimeLimit = ttk.Label(MainWindowRightFrame, text='TimeLimit(min)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                TimeLimitVar = DoubleVar(MainWindowRoot)
                iTimeLimit = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitVar, width=ColumnWidth).grid(row=Row + 1, column=Column)
                Column += 1
                mLickDur = ttk.Label(MainWindowRightFrame, text='LickDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                LickDurVar = DoubleVar(MainWindowRoot)
                iLickDur = ttk.Entry(MainWindowRightFrame, textvariable=LickDurVar, width=ColumnWidth).grid(row=Row + 1, column=Column)
                Column += 1
                mVideoRecording = ttk.Label(MainWindowRightFrame, text='VideoRecording', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                VideoRecordingVar = StringVar(MainWindowRightFrame)
                tVideoRecording = OptionMenu(MainWindowRightFrame, VideoRecordingVar, "ON", "OFF").grid(row=Row + 1, column=Column)

                Str = "ParametersForTask" + str(GetTaskID())

                if os.path.exists(Str + '/MaxTrialNum.dat') == True:
                    with open(Str + '/MaxTrialNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxTrialNumVar.set(pickle.load(PickleInst[GetTaskID()]))
                else:
                    MaxTrialNumVar.set(110)

                if os.path.exists(Str + '/TimeLimit.dat') == True:
                    with open(Str + '/TimeLimit.dat', 'rb') as PickleInst[GetTaskID()]:
                        TimeLimitVar.set(pickle.load(PickleInst[GetTaskID()]))
                else:
                    TimeLimitVar.set(600)

                if os.path.exists(Str + '/LickDur.dat') == True:
                    with open(Str + '/LickDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        LickDurVar.set(pickle.load(PickleInst[GetTaskID()]))
                else:
                    LickDurVar.set(2)

                if os.path.exists(Str + '/VideoRecording.dat') == True:
                    with open(Str + '/VideoRecording.dat', 'rb') as PickleInst[GetTaskID()]:
                        VideoRecordingVar.set(pickle.load(PickleInst[GetTaskID()]))
                else:
                    VideoRecordingVar.set('ON')

                RemoveAllRoiGui()
                PutRoiGui(0, 0, 0, 1)  # Put setting GUI of the indicated ROI on ROI window (ROI number, Detection mode, Threshold direction, ShowSymbol or not)
                PutRoiGui(19, 0, 0, 1)  # Put setting GUI of the indicated ROI on ROI window (ROI number, Detection mode, Threshold direction, ShowSymbol or not)
                #PutRoiGui(2, 0, 0, 1)  # Put setting GUI of the indicated ROI on ROI window (ROI number, Detection mode, Threshold direction, ShowSymbol or not)

                RemoveAllServoGui() # Remove all GUI on the Servo GUI
                PutServoGui(3)  # Put a servo GUI for channel 3 on the Servo GUI
                PutServoGui(5)

                Phase0_Init = 1 # Set a flag which indicating phase0 initialization has done

        if GetSaveTrgStat() == 1:    # If save trigger is activated
            # Parameters will be saved into a folder named "ParametersForTask90"
            Str="ParametersForTask"+str(GetTaskID())   # Assign save folder path
            if os.path.exists(Str) == False:    # If save folder doesn't exist
                os.mkdir(Str)   # Create the folder

            with open(Str+'/MaxTrialNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxTrialNumVar.get(),PickleInst[GetTaskID()])

            with open(Str+'/TimeLimit.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TimeLimitVar.get(),PickleInst[GetTaskID()])

            with open(Str+'/LickDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(LickDurVar.get(), PickleInst[GetTaskID()])

            with open(Str+'/VideoRecording.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(VideoRecordingVar.get(), PickleInst[GetTaskID()])

        if Phase == 1:  # Waiting phase (Task will start when the set time arrives)
            if Phase1_Init == 0: # If the initialization for phase1 has not done
                PutPreTaskButton()  # Put "StartNow" and "Back" button on Main window
                mStatusVar = StringVar(MainWindowRoot)  # Create a variable for status display
                mStatus = ttk.Label(MainWindowRightFrame, textvariable=mStatusVar)  # Create label object and link it with Main window
                mStatus.place(x=10, y=0)    # Place label object on the Main window
                mOngoingResultVar = StringVar(MainWindowRoot)   # Create a variable for progress display
                Phase1_Init = 1 # Flat that phase1 has done
            mStatusVar.set('Linear track (' + str(GetTaskID()) + ')    Waiting...')    # Show current status of the Operant House
            if IsStartTime() == 1:  # Check whether task start time arrives
                StartNow()  # Start task (Phase number will be "2")

        if Phase == 2:  # If it is during task
            if Phase2_Init == 0: # Initialization of the task
                PutEndTaskNowButton()   # Put "TaskEnd" button on Main window
                mStatusVar.set('Linear track (' + str(GetTaskID()) + ')    Start time ' + str(TaskStartedMonth) + '/' + str(TaskStartedDay) + ' ' + str(TaskStartedHour) + ':' + str(TaskStartedMinute) + '    Running')    # Assign latest information about current task into "mStatusVar"
                mOngoingResult = ttk.Label(MainWindowRightFrame, textvariable=mOngoingResultVar)
                mOngoingResult.place(x=10, y=18)

                # Assign task parameter values in StringVars into integer or string variable (to make the cord easeir to read)
                MaxTrialNum = int(MaxTrialNumVar.get())
                TimeLimit = float(TimeLimitVar.get())
                LickDur = float(LickDurVar.get())
                VideoRecording = VideoRecordingVar.get()

                # Declar local variables for this task
                WaterAvailablePos = 1
                TrialNum = 0    # Current trial number
                TaskDur = 0  # This will keep the elapsed time during of task
                NowDrinking = 0 # Use as trigger
                TouchedPanelID = -1
                IsFirstTrial = 1

                if VideoRecording == 'ON':
                    StartRecording()  # Start camera capture / TTL signal output
                StartLickRecording()  # Start an entry of lick log
                LightCycleControlOff()  # Deactivate automatic Light/Dark cycle illumination

                ServoPosInside(3)   # Change the angle of water arm servo connected to Ch3 to inside position
                ServoPosInside(5)

                Writer_TouchEventTxt = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.txt", 'w')  # Initialize the text exporter for a result file
                Writer_TouchEventTxt.write('TrialNum\tResult\t\t\tyyyy/mm/dd\th:m\ts\n')  # Write item name on the result file
                Writer_TouchEventCsv = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.csv", 'w')
                print("Task #" + str(GetTaskID()) + " is started at " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))  # Enter the start time in the console window of Pycharm

                Timer_Start(5)  # Start a timer #5 to measure the duration of the task
                Phase2 = 0  # Start task from the reward phase
                Phase2_Init = 1 # Flag indicating that initialization of Phase2 has done

            if Phase2 == 0:   # Initiation of new trial
                TaskDur = Timer_GetSec(5)
                if IsFirstTrial == 1:
                    ServoPosInside(3)
                    ServoPosInside(5)
                if IsFirstTrial == 0:
                    if WaterAvailablePos == 1:
                        ServoPosInside(3)   #
                    if WaterAvailablePos == -1:
                        ServoPosInside(5)
                Phase2 = 1

            if Phase2 == 1:   # Running phase
                TouchedPanelID = DetectRoiNosepoke()  # Examine whether nozzles are nosepoked (return panel ID. If none of the panels touched, return -1)
                if WaterAvailablePos == 1 and TouchedPanelID== 0 or WaterAvailablePos == -1 and TouchedPanelID== 19 or IsFirstTrial == 1 and TouchedPanelID != -1: # If nosepoking is detected
                    TrialNum += 1
                    if IsFirstTrial == 1:
                        if TouchedPanelID == 0:
                            Writer_TouchEventTxt.write(str(TrialNum) + '\tNozepoke detection at pos #0\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                            Writer_TouchEventCsv.write(str(TrialNum) + ',0,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                            WaterAvailablePos = -1
                        if TouchedPanelID == 19:
                            Writer_TouchEventTxt.write(str(TrialNum) + '\tNozepoke detection at pos #1\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                            Writer_TouchEventCsv.write(str(TrialNum) + ',1,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                            WaterAvailablePos = 1
                    if IsFirstTrial == 0:
                        if WaterAvailablePos==1:
                            Writer_TouchEventTxt.write(str(TrialNum) + '\tNozepoke detection at pos #0\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                            Writer_TouchEventCsv.write(str(TrialNum) + ',0,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                        if WaterAvailablePos==-1:
                            Writer_TouchEventTxt.write(str(TrialNum) + '\tNozepoke detection at pos #1\t' + str(TimeNow.year) + "/" + str(TimeNow.month) + "/" + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the text file
                            Writer_TouchEventCsv.write(str(TrialNum) + ',1,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the response on the csv file
                    mOngoingResultVar.set('TrialNum: ' + str(TrialNum))
                    Timer_Start(0)  # Start lick timer
                    Phase2 = 2  # Start reward phase

                if Timer_GetSec(5) >= TimeLimit * 60:   # If time limit of the task comes
                    TaskDur = Timer_GetSec(5)
                    print("Time limit elapsed")
                    Timer_End(5)    # Stop the timer
                    TaskDur = Timer_GetSec(5)  # Keep the task time
                    Phase2 = -1

            if Phase2 == 2:  # Reward phase
                if Timer_GetSec(0) >= LickDur:   # If the nosepoke duration exceeds the lick duration
                    Timer_End(0) # End timer for measuring lick duration
                    ServoPosMiddle(3)   # Move water nozzle back to the middle position
                    ServoPosMiddle(5)  # Move water nozzle back to the middle position
                    if IsFirstTrial == 0:
                        WaterAvailablePos *= -1
                    Phase2 = 3  # Go to After trial phase

            if Phase2 == 3:  # After trial phase
                if TrialNum < MaxTrialNum:  # If the touch number doesn't exceed the maximum number
                    IsFirstTrial = 0
                    Phase2 = 0
                if TrialNum >= MaxTrialNum:  # If the touch number exceeds the maximum number
                    TaskDur = Timer_GetSec(5)  # Keep the task time
                    Phase2 = -1

            if Phase2 == -1 or GetEndTaskNowButtonStat() == 1:  # If the flag is set to finish the task
                LightCycleControlOn()   # Activate automatic light/dark cycle
                ServoPosMiddle(3)   # Moze servo nozzle into middle position
                ServoPosOutside(5)  # Pull the indicated lever back
                ServoPosOutside(6)
                InfraredLightOff()  # Turn off the infrared LED
                if GetRecordingStat() == 1: # If camera is capturing
                    SetEndRecordingTimer(60)    # Onset a timer to finish video recording after 60 frames (correspond about 2sec) from now

                # Add summary of results into the result file
                Writer_TouchEventTxt.write('TotalNum:' + str(TrialNum) + '%\n')
                Writer_TouchEventTxt.write('SessionStartTime: ' + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()) + "\n")
                Writer_TouchEventTxt.write('SessionEndTime: ' + str(TimeNow.month) + '/' + str(TimeNow.day) + ' ' + str(TimeNow.hour) + ':' + str(TimeNow.minute) + ':' + str(TimeNow.second + (TimeNow.microsecond // 1000) / 1000) + "\n")
                Writer_TouchEventTxt.write('TaskDuration(sec): ' + str(TaskDur) + "\n")
                # Add experimental conditions into the result file
                Writer_TouchEventTxt.write('MaxTrialNum: ' + str(MaxTrialNum) + "\n")
                Writer_TouchEventTxt.write('TimeLimit: ' + str(TimeLimit) + "\n")
                Writer_TouchEventTxt.write('LickDur: ' + str(LickDur)+"\n")
                Writer_TouchEventTxt.write('VideoRecording: ' + str(VideoRecording) + "\n")
                Writer_TouchEventTxt.write('RecordFPS: ' + str(GetRecordFps()) + "\n")  # Recorded frame number per second
                Writer_TouchEventTxt.write(GetRoiSensitivity() + "\n")  # Settings of each ROI
                Writer_TouchEventTxt.write(GetServoAngle() + "\n")  # Set angles of each servo

                Writer_TouchEventTxt.close()    # Close the text exporter for the result file
                Writer_TouchEventCsv.close()
                EndLickRecording()  # End lick log recording

                SendMail(DeviceNameVar.get()+' finished task '+str(GetTaskID())+'. TrialNum:'+str(TrialNum)+'% Dur:'+str(round(Timer_GetSec(5) / 60,1))+' min','The task is finished.') # Send a email (correct number and task duration are added to email title)

                Phase = 1  # Go back to the task-waiting phase
                Phase2 = 0
                Phase2_Init = 0

            SetDispVariable(0, 'Phase2', str(Phase2))  # Display "Phase2" value on the bottom of main window
    return


def Task90():   # Test task (Explanation material: Panel task start)
    global Phase
    Phase0_Init = 0
    Phase1_Init = 0
    Phase2_Init = 0
    while EndFlag == 0:
        OperantHouseUpdate()    # Run house keeping function (This must be executed once per frame)

        if GetBackButtonStat()==1:    # If "Back" button is clicked
            break   # Back to the task select phase
        if Phase == 0:  # Parameter inputs
            if Phase0_Init == 0:    # Make GUI for the setting of the parameters for this task
                RemoveMainRightWidget() # Remove task buttons
                PutStartBackButton()    # Put "start" and "back" buttons

                ColumnWidth = 14    # Width of input columns

                mMaxCorrectNum = ttk.Label(MainWindowRightFrame, text='MaxCorrectNum', width=ColumnWidth).grid(row=0, column=0, sticky=W)    # Put label
                MaxCorrectNumVar = IntVar(MainWindowRoot)  # Declare a variable for input column
                iMaxCorrectNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxCorrectNumVar, width=ColumnWidth).grid(row=1, column=0)  # Create input column and link it with the variable

                mTimeLimit = ttk.Label(MainWindowRightFrame, text='TimeLimit(min)', width=ColumnWidth).grid(row=0, column=1, sticky=W)
                TimeLimitVar = DoubleVar(MainWindowRoot)
                iTimeLimit = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitVar, width=ColumnWidth).grid(row=1, column=1)

                mLickDur = ttk.Label(MainWindowRightFrame, text='LickDur(s)', width=ColumnWidth).grid(row=0, column=2, sticky=W)
                LickDurVar = DoubleVar(MainWindowRoot)
                iLickDur = ttk.Entry(MainWindowRightFrame, textvariable=LickDurVar, width=ColumnWidth).grid(row=1, column=2)


                Str = "ParametersForTask" + str(GetTaskID())
                if os.path.exists(Str + '/MaxCorrectNum.dat') == True:  # If save file named "MaxCorrectNum.dat" exist:
                    with open(Str + '/MaxCorrectNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxCorrectNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Assign loaded data into the variable of this program
                else:  # If save file doesn't exist
                    MaxCorrectNumVar.set(80)  # Assign 80 into the variable

                if os.path.exists(Str + '/TimeLimit.dat') == True:
                    with open(Str + '/TimeLimit.dat', 'rb') as PickleInst[GetTaskID()]:
                        TimeLimitVar.set(pickle.load(PickleInst[GetTaskID()]))
                else:
                    TimeLimitVar.set(600)

                if os.path.exists(Str + '/LickDur.dat') == True:
                    with open(Str + '/LickDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        LickDurVar.set(pickle.load(PickleInst[GetTaskID()]))
                else:
                    LickDurVar.set(2)

                RemoveAllRoiGui()
                PutRoiGui(0, 1, 1, 0)  # Put setting GUI of the indicated ROI on ROI window (ROI number, Detection mode, Threshold direction, ShowSymbol or not)
                PutRoiGui(19, 0, 0, 1)

                RemoveAllDigitalOutGui()    # Remove all GUIs on the Digital out window
                PutDigitalOutGui(10)    # Put the digital output GUI for channel 10 on Digital ouput window
                PutDigitalOutGui(12)
                PutDigitalOutGui(13)

                RemoveAllServoGui() # Remove all GUI on the Servo GUI
                PutServoGui(3)  # Put a servo GUI for channel 3 on the Servo GUI

                Phase0_Init = 1 # Set a flag which indicating phase0 initialization has done

        if GetSaveTrgStat() == 1:    # If save trigger is activated
            # Parameters will be saved into a folder named "ParametersForTask90"
            Str="ParametersForTask"+str(GetTaskID())   # Assign save folder path
            if os.path.exists(Str) == False:    # If save folder doesn't exist
                os.mkdir(Str)   # Create the folder
            with open(Str+'/MaxCorrectNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxCorrectNumVar.get(),PickleInst[GetTaskID()])     # Save a value of "MaxCorrectNumVar" as "MaxCorrectNum.dat" file

            with open(Str+'/TimeLimit.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TimeLimitVar.get(),PickleInst[GetTaskID()])

            with open(Str+'/LickDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(LickDurVar.get(), PickleInst[GetTaskID()])


        if Phase == 1:  # Waiting phase (Task will start when the set time arrives)
            if Phase1_Init == 0: # If the initialization for phase1 has not done
                PutPreTaskButton()  # Put "StartNow" and "Back" button on Main window
                mStatusVar = StringVar(MainWindowRoot)  # Create a variable for status display
                mStatus = ttk.Label(MainWindowRightFrame, textvariable=mStatusVar)  # Create label object and link it with Main window
                mStatus.place(x=10, y=0)    # Place label object on the Main window
                mOngoingResultVar = StringVar(MainWindowRoot)   # Create a variable for progress display
                Phase1_Init = 1 # Flat that phase1 has done
            mStatusVar.set('Test task (' + str(GetTaskID()) + ')    Waiting...')    # Show current status of the Operant House
            if IsStartTime() == 1:  # Check whether task start time arrives
                StartNow()  # Start task (Phase number will be "2")

        if Phase == 2:  # If it is during task
            if Phase2_Init == 0: # Initialization of the task
                PutEndTaskNowButton()   # Put "TaskEnd" button on Main window
                mStatusVar.set('Test task (' + str(GetTaskID()) + ')    Start time ' + str(TaskStartedMonth) + '/' + str(TaskStartedDay) + ' ' + str(TaskStartedHour) + ':' + str(TaskStartedMinute) + '    Running')    # Assign latest information about current task into "mStatusVar"
                mOngoingResult = ttk.Label(MainWindowRightFrame, textvariable=mOngoingResultVar)
                mOngoingResult.place(x=10, y=18)

                # Assign task parameter values in StringVars into integer or string variable (to make the cord easeir to read)
                MaxCorrectNum=int(MaxCorrectNumVar.get())   # Get the value of "MaxCorrectNumVar" and convert it from string to integer and assign into variable named "MaxCorrectNum"
                TimeLimit = float(TimeLimitVar.get())
                LickDur = float(LickDurVar.get())

                # Declar local variables for this task
                CorrectNum = 0
                TaskDur = 0  # This will keep the elapsed time during of task
                NowDrinking = 0

                StartRecording()  # Start camera capture / TTL signal output
                StartLickRecording()  # Start an entry of lick log
                LightCycleControlOff()  # Deactivate automatic Light/Dark cycle illumination
                RoofLightOff()  # Turn off the lights on roof (Digital output Ch13)
                InfraredLightOn()   # Turn on the infrared LED illumination (Digital output Ch12)
                DigitalOutOn(10)        # Turn on cue LED connected to Ch10
                ServoPosInside(3)   # Change the angle of water arm servo connected to Ch3 to inside position
                CreateNormalPanel(0)  # Create a white-filled square panel as panel #0

                Writer_TouchEventTxt = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.txt", 'w')  # Initialize the text exporter for a result file
                Writer_TouchEventTxt.write('TrialNum\tResult\t\t\tyyyy/mm/dd\th:m\ts\n')  # Write item name on the result file
                Writer_TouchEventCsv = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.csv", 'w')
                print("Task #" + str(GetTaskID()) + " is started at " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))  # Enter the start time in the console window of Pycharm

                Timer_Start(5)  # Start a timer #5 to measure the duration of the task
                Phase2 = 2  # Start task from the reward phase
                Phase2_Init = 1 # Flag indicating that initialization of Phase2 has done

            if Phase2 == 0:   # Initiation of new trial
                TaskDur = Timer_GetSec(5)
                ShowPanel(0)    # Display panel #0
                Phase2 = 1

            if Phase2 == 1:   # Panel presentation
                TouchedPanelID = DetectRoiNosepoke()  # Examine which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID == 0: # If mouse touches the panel
                    ServoPosInside(3)    # Move the water nozzle into inside position
                    DigitalOutOn(10)    # Onset cue light
                    HidePanel(0)
                    NowDrinking = 0
                    CorrectNum += 1     # Increase the number of correct response
                    mOngoingResultVar.set('CorrectNum:' + str(CorrectNum))
                    Writer_TouchEventTxt.write(str(CorrectNum)+'\tPanelTouched(Correct)\t'+ str(TimeNow.year)+"/"+str(TimeNow.month)+"/"+str(TimeNow.day)+"\t"+str(TimeNow.hour)+":"+str(TimeNow.minute)+"\t"+str(TimeNow.second)+"."+str(TimeNow.microsecond//1000)+"\n") # Write the response on the text file
                    Writer_TouchEventCsv.write(str(CorrectNum) + ',1,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000)+"\n")  # Write the response on the csv file
                    Phase2 = 2  # Start reward phase

                if Timer_GetSec(5) >= TimeLimit * 60:   # If time limit of the task comes
                    TaskDur = Timer_GetSec(5)
                    print("Time limit elapsed")
                    Timer_End(5)    # Stop the timer
                    Phase2 = -1

            if Phase2 == 2:  # Reward phase
                if DetectRoiNosepoke() == 19 and NowDrinking == 0:    # If the mouse initiates nose poking
                    NowDrinking = 1
                    Timer_Start(0)  # Start lick timer
                if NowDrinking == 1:    # If the nose poke has begun
                    if Timer_GetSec(0) >= LickDur:   # If the nosepoke duration exceeds the lick duration
                        Timer_End(0) # End timer for measuring lick duration
                        ServoPosMiddle(3)   # Move water nozzle back to the middle position
                        DigitalOutOff(10)   # Turn off the cue LED
                        NowDrinking = 0
                        if CorrectNum < MaxCorrectNum:  # If the touch number doesn't exceed the maximum number
                            Phase2 = 0
                        if CorrectNum >= MaxCorrectNum:   # If the touch number exceeds the maximum number
                            TaskDur = Timer_GetSec(5)  # Keep the task time
                            Phase2 = -1 # Go to the task finalizing phase

            if Phase2 == -1 or GetEndTaskNowButtonStat() == 1:  # If the flag is set to finish the task
                LightCycleControlOn()   # Activate automatic light/dark cycle
                ServoPosMiddle(3)   # Moze servo nozzle into middle position
                DeleteAllPanel()    # Remove a panel on touch screen
                InfraredLightOff()  # Turn off the infrared LED
                if GetRecordingStat() == 1: # If camera is capturing
                    SetEndRecordingTimer(60)    # Onset a timer to finish video recording after 60 frames (correspond about 2sec) from now
                # Add summary of results into the result file
                Writer_TouchEventTxt.write('CorrectNum:'+str(CorrectNum)+"\n")
                Writer_TouchEventTxt.write('SessionStartTime: ' + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()) + "\n")
                Writer_TouchEventTxt.write('SessionEndTime: ' + str(TimeNow.month) + '/' + str(TimeNow.day) + ' ' + str(TimeNow.hour) + ':' + str(TimeNow.minute) + ':' + str(TimeNow.second + (TimeNow.microsecond // 1000) / 1000) + "\n")
                Writer_TouchEventTxt.write('TaskDuration(sec): ' + str(TaskDur) + "\n")
                # Add experimental conditions into the result file
                Writer_TouchEventTxt.write('MaxCorrectNum: '+str(MaxCorrectNum)+"\n")
                Writer_TouchEventTxt.write('TimeLimit: ' + str(TimeLimit) + "\n")
                Writer_TouchEventTxt.write('LickDur: ' + str(LickDur)+"\n")
                Writer_TouchEventTxt.write('RecordFPS: ' + str(GetRecordFps()) + "\n")  # Recorded frame number per second
                Writer_TouchEventTxt.write(GetRoiSensitivity() + "\n")  # Settings of each ROI
                Writer_TouchEventTxt.write(GetServoAngle() + "\n")  # Set angles of each servo

                Writer_TouchEventTxt.close()    # Close the text exporter for the result file
                Writer_TouchEventCsv.close()
                EndLickRecording()  # End lick log recording

                SendMail(DeviceNameVar.get()+' finished task '+str(GetTaskID())+'. Correct:'+str(CorrectNum)+' Dur:'+str(round(Timer_GetSec(5) / 60,1))+' min','The task is finished.') # Send a email (correct number and task duration are added to email title)

                Phase = 1  # Go back to the task-waiting phase
                Phase2 = 0
                Phase2_Init = 0

            SetDispVariable(0, 'Phase2', str(Phase2))  # Display "Phase2" value on the bottom of main window
    return

def Task91():   # Test task 2 (Explanation material: Panel task modified)
    global Phase
    Phase0_Init = 0
    Phase1_Init = 0
    Phase2_Init = 0
    while EndFlag == 0:
        OperantHouseUpdate()    # Run house keeping function (This must be executed once per frame)

        if GetBackButtonStat()==1:    # If "Back" button is clicked
            break   # Back to the task select phase
        if Phase == 0:  # Parameter inputs
            if Phase0_Init == 0:    # Make GUI for the setting of the parameters for this task
                RemoveMainRightWidget() # Remove task buttons
                PutStartBackButton()    # Put "start" and "back" buttons

                ColumnWidth = 14    # Width of input columns

                mMaxCorrectNum = ttk.Label(MainWindowRightFrame, text='MaxCorrectNum', width=ColumnWidth).grid(row=0, column=0, sticky=W)    # Put label
                MaxCorrectNumVar = IntVar(MainWindowRoot)  # Declare a variable for input column
                iMaxCorrectNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxCorrectNumVar, width=ColumnWidth).grid(row=1, column=0)  # Create input column and link it with the variable

                mMaxTrialNum = ttk.Label(MainWindowRightFrame, text='MaxTrialNum', width=ColumnWidth).grid(row=0, column=1, sticky=W)
                MaxTrialNumVar = IntVar(MainWindowRoot)  # Declare a variable for input column
                iMaxTrialNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxTrialNumVar, width=ColumnWidth).grid(row=1, column=1)

                mTimeLimit = ttk.Label(MainWindowRightFrame, text='TimeLimit(min)', width=ColumnWidth).grid(row=0, column=2, sticky=W)
                TimeLimitVar = DoubleVar(MainWindowRoot)
                iTimeLimit = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitVar, width=ColumnWidth).grid(row=1, column=2)

                mPunishDur = ttk.Label(MainWindowRightFrame, text='PunishDur(s)', width=ColumnWidth).grid(row=0, column=3, sticky=W)
                PunishDurVar = DoubleVar(MainWindowRoot)
                iPunishDur = ttk.Entry(MainWindowRightFrame, textvariable=PunishDurVar, width=ColumnWidth).grid(row=1, column=3)

                mLickDur = ttk.Label(MainWindowRightFrame, text='LickDur(s)', width=ColumnWidth).grid(row=0, column=4, sticky=W)
                LickDurVar = DoubleVar(MainWindowRoot)
                iLickDur = ttk.Entry(MainWindowRightFrame, textvariable=LickDurVar, width=ColumnWidth).grid(row=1, column=4)


                Str = "ParametersForTask" + str(GetTaskID())
                if os.path.exists(Str + '/MaxCorrectNum.dat') == True:  # If save file named "MaxCorrectNum.dat" exist:
                    with open(Str + '/MaxCorrectNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxCorrectNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Assign loaded data into the variable of this program
                else:  # If save file doesn't exist
                    MaxCorrectNumVar.set(80)  # Assign 80 into the variable

                if os.path.exists(Str + '/MaxTrialNum.dat') == True:
                    with open(Str + '/MaxTrialNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxTrialNumVar.set(pickle.load(PickleInst[GetTaskID()]))
                else:
                    MaxTrialNumVar.set(110)

                if os.path.exists(Str + '/TimeLimit.dat') == True:
                    with open(Str + '/TimeLimit.dat', 'rb') as PickleInst[GetTaskID()]:
                        TimeLimitVar.set(pickle.load(PickleInst[GetTaskID()]))
                else:
                    TimeLimitVar.set(600)

                if os.path.exists(Str + '/PunishDur.dat') == True:
                    with open(Str + '/PunishDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishDurVar.set(pickle.load(PickleInst[GetTaskID()]))
                else:
                    PunishDurVar.set(10)

                if os.path.exists(Str + '/LickDur.dat') == True:
                    with open(Str + '/LickDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        LickDurVar.set(pickle.load(PickleInst[GetTaskID()]))
                else:
                    LickDurVar.set(2)

                RemoveAllRoiGui()
                PutRoiGui(0, 1, 1, 0)  # Put setting GUI of the indicated ROI on ROI window (ROI number, Detection mode, Threshold direction, ShowSymbol or not)
                PutRoiGui(1, 1, 1, 0)
                PutRoiGui(19, 0, 0, 1)

                RemoveAllDigitalOutGui()    # Remove all GUIs on the Digital out window
                PutDigitalOutGui(10)    # Put the digital output GUI for channel 10 on Digital ouput window
                PutDigitalOutGui(12)
                PutDigitalOutGui(13)

                RemoveAllServoGui() # Remove all GUI on the Servo GUI
                PutServoGui(3)  # Put a servo GUI for channel 3 on the Servo GUI

                Phase0_Init = 1 # Set a flag which indicating phase0 initialization has done

        if GetSaveTrgStat() == 1:    # If save trigger is activated
            # Parameters will be saved into a folder named "ParametersForTask90"
            Str="ParametersForTask"+str(GetTaskID())   # Assign save folder path
            if os.path.exists(Str) == False:    # If save folder doesn't exist
                os.mkdir(Str)   # Create the folder
            with open(Str+'/MaxCorrectNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxCorrectNumVar.get(),PickleInst[GetTaskID()])     # Save a value of "MaxCorrectNumVar" as "MaxCorrectNum.dat" file

            with open(Str+'/MaxTrialNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxTrialNumVar.get(),PickleInst[GetTaskID()])

            with open(Str+'/TimeLimit.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TimeLimitVar.get(),PickleInst[GetTaskID()])

            with open(Str+'/PunishDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishDurVar.get(), PickleInst[GetTaskID()])

            with open(Str+'/LickDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(LickDurVar.get(), PickleInst[GetTaskID()])


        if Phase == 1:  # Waiting phase (Task will start when the set time arrives)
            if Phase1_Init == 0: # If the initialization for phase1 has not done
                PutPreTaskButton()  # Put "StartNow" and "Back" button on Main window
                mStatusVar = StringVar(MainWindowRoot)  # Create a variable for status display
                mStatus = ttk.Label(MainWindowRightFrame, textvariable=mStatusVar)  # Create label object and link it with Main window
                mStatus.place(x=10, y=0)    # Place label object on the Main window
                mOngoingResultVar = StringVar(MainWindowRoot)   # Create a variable for progress display
                Phase1_Init = 1 # Flat that phase1 has done
            mStatusVar.set('Test2 task (' + str(GetTaskID()) + ')    Waiting...')    # Show current status of the Operant House
            if IsStartTime() == 1:  # Check whether task start time arrives
                StartNow()  # Start task (Phase number will be "2")

        if Phase == 2:  # If it is during task
            if Phase2_Init == 0: # Initialization of the task
                PutEndTaskNowButton()   # Put "TaskEnd" button on Main window
                mStatusVar.set('Test2 task (' + str(GetTaskID()) + ')    Start time ' + str(TaskStartedMonth) + '/' + str(TaskStartedDay) + ' ' + str(TaskStartedHour) + ':' + str(TaskStartedMinute) + '    Running')    # Assign latest information about current task into "mStatusVar"
                mOngoingResult = ttk.Label(MainWindowRightFrame, textvariable=mOngoingResultVar)
                mOngoingResult.place(x=10, y=18)

                # Assign task parameter values in StringVars into integer or string variable (to make the cord easeir to read)
                MaxCorrectNum = int(MaxCorrectNumVar.get())   # Get the value of "MaxCorrectNumVar" and convert it from string to integer and assign into variable named "MaxCorrectNum"
                MaxTrialNum = int(MaxTrialNumVar.get())
                TimeLimit = float(TimeLimitVar.get())
                PunishDur = float(PunishDurVar.get())
                LickDur = float(LickDurVar.get())

                # Declar local variables for this task
                TrialNum = 0    # Current trial number
                CorrectNum = 0  # Current correct trial number
                IncorrectNum = 0    # Current incorrect trial number
                CorrectRate = 0.0   # Current correct rate
                TaskDur = 0  # This will keep the elapsed time during of task
                NowDrinking = 0 # Use as trigger
                CorrectPanelID = 0  # ID number of current correct panel (0 or 1)

                StartRecording()  # Start camera capture / TTL signal output
                StartLickRecording()  # Start an entry of lick log
                LightCycleControlOff()  # Deactivate automatic Light/Dark cycle illumination
                RoofLightOff()  # Turn off the lights on roof (Digital output Ch13)
                InfraredLightOn()   # Turn on the infrared LED illumination (Digital output Ch12)
                DigitalOutOn(10)        # Turn on cue LED connected to Ch10
                ServoPosInside(3)   # Change the angle of water arm servo connected to Ch3 to inside position
                CreateNormalPanel(0)  # Create a white-filled square panel as panel #0
                CreateNormalPanel(1)

                Writer_TouchEventTxt = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.txt", 'w')  # Initialize the text exporter for a result file
                Writer_TouchEventTxt.write('TrialNum\tResult\t\t\tyyyy/mm/dd\th:m\ts\n')  # Write item name on the result file
                Writer_TouchEventCsv = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.csv", 'w')
                print("Task #" + str(GetTaskID()) + " is started at " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))  # Enter the start time in the console window of Pycharm

                Timer_Start(5)  # Start a timer #5 to measure the duration of the task
                Phase2 = 2  # Start task from the reward phase
                Phase2_Init = 1 # Flag indicating that initialization of Phase2 has done

            if Phase2 == 0:   # Initiation of new trial
                TaskDur = Timer_GetSec(5)
                CorrectPanelID = int(random.random()*2) # Determine which panel will be assigned as "correct"
                print('CorrectPanelID: ' + str(CorrectPanelID))
                ShowPanel(CorrectPanelID)    # Display panel #0
                Phase2 = 1

            if Phase2 == 1:   # Panel presentation
                TouchedPanelID = DetectRoiNosepoke()  # Examine which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID != -1 and TouchedPanelID != 19: # If mouse touches the panel
                    TrialNum += 1
                    if TouchedPanelID == CorrectPanelID:    # If touched panel is assigned as correct
                        ServoPosInside(3)    # Move the water nozzle into inside position
                        DigitalOutOn(10)    # Onset cue light
                        HidePanel(0)    # Turn off panel #0
                        HidePanel(1)    # Turn off panel #1
                        NowDrinking = 0
                        CorrectNum += 1     # Increase the number of correct response
                        Writer_TouchEventTxt.write(str(TrialNum)+'\tPanelTouched(Correct)\t'+ str(TimeNow.year)+"/"+str(TimeNow.month)+"/"+str(TimeNow.day)+"\t"+str(TimeNow.hour)+":"+str(TimeNow.minute)+"\t"+str(TimeNow.second)+"."+str(TimeNow.microsecond//1000)+"\n") # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',1,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000)+"\n")  # Write the response on the csv file
                        Phase2 = 2  # Start reward phase

                    if TouchedPanelID != CorrectPanelID:    # If touched panel is assigned as incorrect
                        ServoPosOutside(3)    # Move the water nozzle into inside position
                        HidePanel(0)
                        HidePanel(1)
                        RoofLightOn()   # Turn on the ceiling illumination
                        IncorrectNum += 1     # Increase the number of correct response
                        Writer_TouchEventTxt.write(str(TrialNum)+'\tPanelTouched(Incorrect)\t'+ str(TimeNow.year)+"/"+str(TimeNow.month)+"/"+str(TimeNow.day)+"\t"+str(TimeNow.hour)+":"+str(TimeNow.minute)+"\t"+str(TimeNow.second)+"."+str(TimeNow.microsecond//1000)+"\n") # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',2,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000)+"\n")  # Write the response on the csv file
                        Timer_Start(0)  # Start punishment timer
                        Phase2 = 3  # Start punish phase
                    mOngoingResultVar.set('CorrectNum: ' + str(CorrectNum) + '  IncorrectNum: ' + str(IncorrectNum) + '  TrialNum: ' + str(TrialNum))

                if Timer_GetSec(5) >= TimeLimit * 60:   # If time limit of the task comes
                    TaskDur = Timer_GetSec(5)
                    print("Time limit elapsed")
                    Timer_End(5)    # Stop the timer
                    Phase2 = -1

            if Phase2 == 2:  # Reward phase
                if DetectRoiNosepoke() == 19 and NowDrinking == 0:    # If the mouse initiates nose poking
                    NowDrinking = 1
                    Timer_Start(0)  # Start lick timer
                if NowDrinking == 1:    # If the nose poke has begun
                    if Timer_GetSec(0) >= LickDur:   # If the nosepoke duration exceeds the lick duration
                        Timer_End(0) # End timer for measuring lick duration
                        ServoPosMiddle(3)   # Move water nozzle back to the middle position
                        DigitalOutOff(10)   # Turn off the cue LED
                        NowDrinking = 0
                        Phase2 = 4  # Go to After trial phase

            if Phase2 == 3:  # Punishment phase
                if Timer_GetSec(0) >= PunishDur:  # If punishment time is passed
                    Timer_End(0)  # End punishment timer1
                    RoofLightOff()
                    ServoPosMiddle(3)  # Move water nozzle to the intermediate position
                    Phase2 = 4  # Go to After trial phase

            if Phase2 == 4:  # After trial phase
                if CorrectNum < MaxCorrectNum and TrialNum < MaxTrialNum:  # If the touch number doesn't exceed the maximum number
                    Phase2 = 0
                if CorrectNum >= MaxCorrectNum or TrialNum >= MaxTrialNum:  # If the touch number exceeds the maximum number
                    TaskDur = Timer_GetSec(5)  # Keep the task time
                    Phase2 = -1  # Go to the task finalizing phase


            if Phase2 == -1 or GetEndTaskNowButtonStat() == 1:  # If the flag is set to finish the task
                LightCycleControlOn()   # Activate automatic light/dark cycle
                ServoPosMiddle(3)   # Moze servo nozzle into middle position
                DeleteAllPanel()    # Remove a panel on touch screen
                InfraredLightOff()  # Turn off the infrared LED
                if GetRecordingStat() == 1: # If camera is capturing
                    SetEndRecordingTimer(60)    # Onset a timer to finish video recording after 60 frames (correspond about 2sec) from now

                # Add summary of results into the result file
                if CorrectNum > 0 or IncorrectNum > 0:
                    CorrectRate = int(CorrectNum * 100.0 / TrialNum)
                Writer_TouchEventTxt.write('TotalNum:' + str(TrialNum) + '  CorrectNum:' + str(CorrectNum) + '  IncorrectNum:' + str(IncorrectNum) + '  CorrectRate:' + str(CorrectRate) + '%\n')
                Writer_TouchEventTxt.write('SessionStartTime: ' + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()) + "\n")
                Writer_TouchEventTxt.write('SessionEndTime: ' + str(TimeNow.month) + '/' + str(TimeNow.day) + ' ' + str(TimeNow.hour) + ':' + str(TimeNow.minute) + ':' + str(TimeNow.second + (TimeNow.microsecond // 1000) / 1000) + "\n")
                Writer_TouchEventTxt.write('TaskDuration(sec): ' + str(TaskDur) + "\n")
                # Add experimental conditions into the result file
                Writer_TouchEventTxt.write('MaxCorrectNum: '+str(MaxCorrectNum)+"\n")
                Writer_TouchEventTxt.write('MaxTrialNum: ' + str(MaxTrialNum) + "\n")
                Writer_TouchEventTxt.write('TimeLimit: ' + str(TimeLimit) + "\n")
                Writer_TouchEventTxt.write('PunishDur: ' + str(TimeLimit) + "\n")
                Writer_TouchEventTxt.write('LickDur: ' + str(LickDur)+"\n")
                Writer_TouchEventTxt.write('RecordFPS: ' + str(GetRecordFps()) + "\n")  # Recorded frame number per second
                Writer_TouchEventTxt.write(GetRoiSensitivity() + "\n")  # Settings of each ROI
                Writer_TouchEventTxt.write(GetServoAngle() + "\n")  # Set angles of each servo

                Writer_TouchEventTxt.close()    # Close the text exporter for the result file
                Writer_TouchEventCsv.close()
                EndLickRecording()  # End lick log recording

                SendMail(DeviceNameVar.get()+' finished task '+str(GetTaskID())+'. TrialNum:'+str(TrialNum)+' Correct:'+str(CorrectNum)+' Incorrect:'+str(IncorrectNum)+' Rate:'+str(CorrectRate)+'% Dur:'+str(round(Timer_GetSec(5) / 60,1))+' min','The task is finished.') # Send a email (correct number and task duration are added to email title)

                Phase = 1  # Go back to the task-waiting phase
                Phase2 = 0
                Phase2_Init = 0

            SetDispVariable(0, 'Phase2', str(Phase2))  # Display "Phase2" value on the bottom of main window
    return

def Task92():   # Test task 3 (Explanation material: Panel task finish)
    global Phase
    Phase0_Init = 0
    Phase1_Init = 0
    Phase2_Init = 0
    while EndFlag == 0:
        OperantHouseUpdate()    # Run house keeping function (This must be executed once per frame)

        if GetBackButtonStat()==1:    # If "Back" button is clicked
            break   # Back to the task select phase
        if Phase == 0:  # Parameter inputs
            if Phase0_Init == 0:    # Make GUI for the setting of the parameters for this task
                RemoveMainRightWidget() # Remove task buttons
                PutStartBackButton()    # Put "start" and "back" buttons

                ColumnWidth = 14    # Width of input columns
                Row = 0
                Column = 0
                mMaxCorrectNum = ttk.Label(MainWindowRightFrame, text='MaxCorrectNum', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                MaxCorrectNumVar = IntVar(MainWindowRoot)  # Declare a variable for input column
                iMaxCorrectNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxCorrectNumVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Create input column and link it with the variable
                Column += 1
                mMaxTrialNum = ttk.Label(MainWindowRightFrame, text='MaxTrialNum', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                MaxTrialNumVar = IntVar(MainWindowRoot)  # Declare a variable for input column
                iMaxTrialNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxTrialNumVar, width=ColumnWidth).grid(row=Row + 1, column=Column)
                Column += 1
                mTimeLimit = ttk.Label(MainWindowRightFrame, text='TimeLimit(min)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                TimeLimitVar = DoubleVar(MainWindowRoot)
                iTimeLimit = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitVar, width=ColumnWidth).grid(row=Row + 1, column=Column)
                Column += 1
                mPunishDur = ttk.Label(MainWindowRightFrame, text='PunishDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                PunishDurVar = DoubleVar(MainWindowRoot)
                iPunishDur = ttk.Entry(MainWindowRightFrame, textvariable=PunishDurVar, width=ColumnWidth).grid(row=Row + 1, column=Column)
                Column += 1
                mLickDur = ttk.Label(MainWindowRightFrame, text='LickDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                LickDurVar = DoubleVar(MainWindowRoot)
                iLickDur = ttk.Entry(MainWindowRightFrame, textvariable=LickDurVar, width=ColumnWidth).grid(row=Row + 1, column=Column)
                Column += 1
                mNextTask = ttk.Label(MainWindowRightFrame, text='NextTask#', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # The task number indicated here will be the next task if the correct rate exceeds "NextTaskTh"
                NextTaskVar = IntVar(MainWindowRoot)
                iNextTask = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskVar, width=ColumnWidth).grid(row=Row + 1, column=Column)
                Column += 1
                mNextTaskTh = ttk.Label(MainWindowRightFrame, text='NextTaskTh%', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)   # Correct rate threshold to switch to the next task
                NextTaskThVar = DoubleVar(MainWindowRoot)
                iNextTaskTh = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskThVar, width=ColumnWidth).grid(row=Row + 1, column=Column)

                Row += 2  # Begin a new line
                Column = 0

                mPanelType = ttk.Label(MainWindowRightFrame, text='PanelType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Type of panel, Normal: white rectangle panel, Blink: white rectangle bilnking panel, Textured: User custom image (Can be upload at "MainWindow -> Setting -> Panel* texture")
                PanelTypeVar = StringVar(MainWindowRightFrame)
                tPanelType = OptionMenu(MainWindowRightFrame, PanelTypeVar, "Normal", "Blink", "Textured").grid(row=Row + 1, column=Column, sticky=W)
                Column += 1
                mWaterCueType = ttk.Label(MainWindowRightFrame, text='WaterCueType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # If chose blink, reward cue will blink
                WaterCueTypeVar = StringVar(MainWindowRightFrame)
                tWaterCueType = OptionMenu(MainWindowRightFrame, WaterCueTypeVar, "Normal", "Blink").grid(row=Row + 1, column=Column, sticky=W)
                Column += 1
                mAwsOn = ttk.Label(MainWindowRightFrame, text='AWS', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # If ON, complemental water supply is applied after end of each session
                AwsOnVar = StringVar(MainWindowRoot)
                tAwsOn = OptionMenu(MainWindowRightFrame, AwsOnVar, "ON", "OFF").grid(row=Row + 1, column=Column, sticky=W)

                Str = "ParametersForTask" + str(GetTaskID())
                if os.path.exists(Str + '/MaxCorrectNum.dat') == True:  # If save file named "MaxCorrectNum.dat" exist:
                    with open(Str + '/MaxCorrectNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxCorrectNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Assign loaded data into the variable of this program
                else:  # If save file doesn't exist
                    MaxCorrectNumVar.set(80)  # Assign 80 into the variable

                if os.path.exists(Str + '/MaxTrialNum.dat') == True:
                    with open(Str + '/MaxTrialNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxTrialNumVar.set(pickle.load(PickleInst[GetTaskID()]))
                else:
                    MaxTrialNumVar.set(110)

                if os.path.exists(Str + '/TimeLimit.dat') == True:
                    with open(Str + '/TimeLimit.dat', 'rb') as PickleInst[GetTaskID()]:
                        TimeLimitVar.set(pickle.load(PickleInst[GetTaskID()]))
                else:
                    TimeLimitVar.set(600)

                if os.path.exists(Str + '/PunishDur.dat') == True:
                    with open(Str + '/PunishDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishDurVar.set(pickle.load(PickleInst[GetTaskID()]))
                else:
                    PunishDurVar.set(10)

                if os.path.exists(Str + '/LickDur.dat') == True:
                    with open(Str + '/LickDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        LickDurVar.set(pickle.load(PickleInst[GetTaskID()]))
                else:
                    LickDurVar.set(2)

                if os.path.exists(Str + '/NextTask.dat') == True:
                    with open(Str + '/NextTask.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskVar.set(92)  # Default value

                if os.path.exists(Str + '/NextTaskTh.dat') == True:
                    with open(Str + '/NextTaskTh.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskThVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskThVar.set(80)  # Default value

                if os.path.exists(Str + '/PanelType.dat') == True:
                    with open(Str + '/PanelType.dat', 'rb') as PickleInst[GetTaskID()]:
                        PanelTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    PanelTypeVar.set('Blink')  # Default value

                if os.path.exists(Str + '/WaterCueType.dat') == True:
                    with open(Str + '/WaterCueType.dat', 'rb') as PickleInst[GetTaskID()]:
                        WaterCueTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    WaterCueTypeVar.set('Blink')  # Default value

                if os.path.exists(Str + '/AwsOn.dat') == True:
                    with open(Str + '/AwsOn.dat', 'rb') as PickleInst[GetTaskID()]:
                        AwsOnVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    AwsOnVar.set('ON')  # Default value

                RemoveAllRoiGui()
                PutRoiGui(0, 1, 1, 0)  # Put setting GUI of the indicated ROI on ROI window (ROI number, Detection mode, Threshold direction, ShowSymbol or not)
                PutRoiGui(1, 1, 1, 0)
                PutRoiGui(19, 0, 0, 1)

                RemoveAllDigitalOutGui()    # Remove all GUIs on the Digital out window
                PutDigitalOutGui(10)    # Put the digital output GUI for channel 10 on Digital ouput window
                PutDigitalOutGui(12)
                PutDigitalOutGui(13)

                RemoveAllServoGui() # Remove all GUI on the Servo GUI
                PutServoGui(3)  # Put a servo GUI for channel 3 on the Servo GUI

                Phase0_Init = 1 # Set a flag which indicating phase0 initialization has done

        if GetSaveTrgStat() == 1:    # If save trigger is activated
            # Parameters will be saved into a folder named "ParametersForTask90"
            Str="ParametersForTask"+str(GetTaskID())   # Assign save folder path
            if os.path.exists(Str) == False:    # If save folder doesn't exist
                os.mkdir(Str)   # Create the folder
            with open(Str+'/MaxCorrectNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxCorrectNumVar.get(),PickleInst[GetTaskID()])     # Save a value of "MaxCorrectNumVar" as "MaxCorrectNum.dat" file

            with open(Str+'/MaxTrialNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxTrialNumVar.get(),PickleInst[GetTaskID()])

            with open(Str+'/TimeLimit.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TimeLimitVar.get(),PickleInst[GetTaskID()])

            with open(Str+'/PunishDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishDurVar.get(), PickleInst[GetTaskID()])

            with open(Str+'/LickDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(LickDurVar.get(), PickleInst[GetTaskID()])

            with open(Str + '/NextTask.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskVar.get(), PickleInst[GetTaskID()])

            with open(Str+'/NextTaskTh.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskThVar.get(), PickleInst[GetTaskID()])

            with open(Str+'/PanelType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PanelTypeVar.get(), PickleInst[GetTaskID()])

            with open(Str+'/WaterCueType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(WaterCueTypeVar.get(), PickleInst[GetTaskID()])

            with open(Str+'/AwsOn.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(AwsOnVar.get(), PickleInst[GetTaskID()])

        if Phase == 1:  # Waiting phase (Task will start when the set time arrives)
            if Phase1_Init == 0: # If the initialization for phase1 has not done
                PutPreTaskButton()  # Put "StartNow" and "Back" button on Main window
                mStatusVar = StringVar(MainWindowRoot)  # Create a variable for status display
                mStatus = ttk.Label(MainWindowRightFrame, textvariable=mStatusVar)  # Create label object and link it with Main window
                mStatus.place(x=10, y=0)    # Place label object on the Main window
                mOngoingResultVar = StringVar(MainWindowRoot)   # Create a variable for progress display
                Phase1_Init = 1 # Flat that phase1 has done
            mStatusVar.set('Test3 task (' + str(GetTaskID()) + ')    Waiting...')    # Show current status of the Operant House
            if IsStartTime() == 1:  # Check whether task start time arrives
                StartNow()  # Start task (Phase number will be "2")

        if Phase == 2:  # If it is during task
            if Phase2_Init == 0: # Initialization of the task
                PutEndTaskNowButton()   # Put "TaskEnd" button on Main window
                mStatusVar.set('Test3 task (' + str(GetTaskID()) + ')    Start time ' + str(TaskStartedMonth) + '/' + str(TaskStartedDay) + ' ' + str(TaskStartedHour) + ':' + str(TaskStartedMinute) + '    Running')    # Assign latest information about current task into "mStatusVar"
                mOngoingResult = ttk.Label(MainWindowRightFrame, textvariable=mOngoingResultVar)
                mOngoingResult.place(x=10, y=18)

                # Assign task parameter values in StringVars into integer or string variable (to make the cord easeir to read)
                MaxCorrectNum = int(MaxCorrectNumVar.get())   # Get the value of "MaxCorrectNumVar" and convert it from string to integer and assign into variable named "MaxCorrectNum"
                MaxTrialNum = int(MaxTrialNumVar.get())
                TimeLimit = float(TimeLimitVar.get())
                PunishDur = float(PunishDurVar.get())
                LickDur = float(LickDurVar.get())
                NextTask = int(NextTaskVar.get())
                NextTaskTh = float(NextTaskThVar.get())
                PanelType = PanelTypeVar.get()
                WaterCueType = WaterCueTypeVar.get()
                AwsOn = AwsOnVar.get()

                # Declar local variables for this task
                TrialNum = 0    # Current trial number
                CorrectNum = 0  # Current correct trial number
                IncorrectNum = 0    # Current incorrect trial number
                CorrectRate = 0.0   # Current correct rate
                TaskDur = 0  # This will keep the elapsed time during of task
                NowDrinking = 0 # Use as trigger
                CorrectPanelID = 0  # ID number of current correct panel (0 or 1)
                AWS_Latency = 20    # Latency to start AWS (sec)

                StartRecording()  # Start camera capture / TTL signal output
                StartLickRecording()  # Start an entry of lick log
                LightCycleControlOff()  # Deactivate automatic Light/Dark cycle illumination
                RoofLightOff()  # Turn off the lights on roof (Digital output Ch13)
                InfraredLightOn()   # Turn on the infrared LED illumination (Digital output Ch12)
                if WaterCueType == 'Normal':
                    DigitalOutOn(10)    # Turn on cue LED connected to Ch10
                if WaterCueType == 'Blink':
                    DigitalOutBlinkOn(10)   # Start blinking of cue LED connected to Ch10
                ServoPosInside(3)   # Change the angle of water arm servo connected to Ch3 to inside position
                if PanelType == 'Normal':
                    CreateNormalPanel(0)  # Create a white-filled square panel as panel #0
                    CreateNormalPanel(1)
                if PanelType == 'Blink':
                    CreateBlinkPanel(0)  # Create a white-filled square blinking panel #0
                    CreateBlinkPanel(1)
                if PanelType == 'Textured':
                    CreateTexturedPanel(0,0)  # Create a user uploaded image panel #0
                    CreateTexturedPanel(1,0)

                Writer_TouchEventTxt = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.txt", 'w')  # Initialize the text exporter for a result file
                Writer_TouchEventTxt.write('TrialNum\tResult\t\t\tyyyy/mm/dd\th:m\ts\n')  # Write item name on the result file
                Writer_TouchEventCsv = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.csv", 'w')
                print("Task #" + str(GetTaskID()) + " is started at " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))  # Enter the start time in the console window of Pycharm

                Timer_Start(5)  # Start a timer #5 to measure the duration of the task
                Phase2 = 2  # Start task from the reward phase
                Phase2_Init = 1 # Flag indicating that initialization of Phase2 has done

            if Phase2 == 0:   # Initiation of new trial
                TaskDur = Timer_GetSec(5)
                CorrectPanelID = int(random.random()*2) # Determine which panel will be assigned as "correct"
                print('CorrectPanelID: ' + str(CorrectPanelID))
                ShowPanel(CorrectPanelID)    # Display panel #0
                Phase2 = 1

            if Phase2 == 1:   # Panel presentation
                TouchedPanelID = DetectRoiNosepoke()  # Examine which panel is touched (return panel ID. If none of the panels touched, return -1)
                if TouchedPanelID != -1 and TouchedPanelID != 19: # If mouse touches the panel
                    TrialNum += 1
                    if TouchedPanelID == CorrectPanelID:    # If touched panel is assigned as correct
                        ServoPosInside(3)    # Move the water nozzle into inside position
                        if WaterCueType == 'Normal':
                            DigitalOutOn(10)  # Turn on cue LED connected to Ch10
                        if WaterCueType == 'Blink':
                            DigitalOutBlinkOn(10)  # Start blinking of cue LED connected to Ch10
                        HidePanel(0)    # Turn off panel #0
                        HidePanel(1)    # Turn off panel #1
                        NowDrinking = 0
                        CorrectNum += 1     # Increase the number of correct response
                        Writer_TouchEventTxt.write(str(TrialNum)+'\tPanelTouched(Correct)\t'+ str(TimeNow.year)+"/"+str(TimeNow.month)+"/"+str(TimeNow.day)+"\t"+str(TimeNow.hour)+":"+str(TimeNow.minute)+"\t"+str(TimeNow.second)+"."+str(TimeNow.microsecond//1000)+"\n") # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',1,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000)+"\n")  # Write the response on the csv file
                        Phase2 = 2  # Start reward phase

                    if TouchedPanelID != CorrectPanelID:    # If touched panel is assigned as incorrect
                        ServoPosOutside(3)    # Move the water nozzle into inside position
                        HidePanel(0)
                        HidePanel(1)
                        RoofLightOn()   # Turn on the ceiling illumination
                        IncorrectNum += 1     # Increase the number of correct response
                        Writer_TouchEventTxt.write(str(TrialNum)+'\tPanelTouched(Incorrect)\t'+ str(TimeNow.year)+"/"+str(TimeNow.month)+"/"+str(TimeNow.day)+"\t"+str(TimeNow.hour)+":"+str(TimeNow.minute)+"\t"+str(TimeNow.second)+"."+str(TimeNow.microsecond//1000)+"\n") # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',2,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000)+"\n")  # Write the response on the csv file
                        Timer_Start(0)  # Start punishment timer
                        Phase2 = 3  # Start punish phase
                    mOngoingResultVar.set('CorrectNum: ' + str(CorrectNum) + '  IncorrectNum: ' + str(IncorrectNum) + '  TrialNum: ' + str(TrialNum))

                if Timer_GetSec(5) >= TimeLimit * 60:   # If time limit of the task comes
                    TaskDur = Timer_GetSec(5)
                    print("Time limit elapsed")
                    Timer_End(5)    # Stop the timer
                    Phase2 = 5

            if Phase2 == 2:  # Reward phase
                if DetectRoiNosepoke() == 19 and NowDrinking == 0:    # If the mouse initiates nose poking
                    NowDrinking = 1
                    Timer_Start(0)  # Start lick timer
                if NowDrinking == 1:    # If the nose poke has begun
                    if Timer_GetSec(0) >= LickDur:   # If the nosepoke duration exceeds the lick duration
                        Timer_End(0) # End timer for measuring lick duration
                        ServoPosMiddle(3)   # Move water nozzle back to the middle position
                        DigitalOutOff(10)   # Turn off the cue LED
                        NowDrinking = 0
                        Phase2 = 4  # Go to After trial phase

            if Phase2 == 3:  # Punishment phase
                if Timer_GetSec(0) >= PunishDur:  # If punishment time is passed
                    Timer_End(0)  # End punishment timer1
                    RoofLightOff()
                    ServoPosMiddle(3)  # Move water nozzle to the intermediate position
                    Phase2 = 4  # Go to After trial phase

            if Phase2 == 4:  # After trial phase
                if CorrectNum < MaxCorrectNum and TrialNum < MaxTrialNum:  # If the touch number doesn't exceed the maximum number
                    Phase2 = 0
                if CorrectNum >= MaxCorrectNum or TrialNum >= MaxTrialNum:  # If the touch number exceeds the maximum number
                    TaskDur = Timer_GetSec(5)  # Keep the task time
                    Phase2 = 5

            if Phase2 == 5:
                HideAllPanel()
                if CorrectNum < MaxCorrectNum and AwsOn == 'ON':  # If mouse didn't achieved the max correct response
                    Timer_Start(0)
                    Phase2 = 6
                if CorrectNum == MaxCorrectNum or AwsOn == 'OFF':  # If mouse achieved the max correct response
                    Phase2 = -1

            if Phase2 == 6:  # Wait until complemental water supply is started
                if Timer_GetSec(0) >= AWS_Latency:  # If it past indicated latency to start complemental water supply
                    Timer_End(0)
                    ArbitaryWaterSupplyDur = (MaxCorrectNum - CorrectNum) * LickDur * 1000  # Calculate the duration of complemental water supply
                    if WaterCueType == 'Normal':
                        StartArbitaryWaterSupply(3, 10, 0, ArbitaryWaterSupplyDur)  # Start complemental water supply
                    if WaterCueType == 'Blink':
                        StartArbitaryWaterSupply(3, 10, 1, ArbitaryWaterSupplyDur)
                    print("Arbitrary water supply start")
                    Phase2 = 7  # Start AWS

            if Phase2 == 7: # Keep checking until complemental water supply is finished
                if GetArbitaryWaterSupplyStat() == 1:  # If the complemental water supply is finished
                    Phase2 = -1

            if Phase2 == -1 or GetEndTaskNowButtonStat() == 1:  # If the flag is set to finish the task
                LightCycleControlOn()   # Activate automatic light/dark cycle
                ServoPosMiddle(3)   # Moze servo nozzle into middle position
                DeleteAllPanel()    # Remove a panel on touch screen
                InfraredLightOff()  # Turn off the infrared LED
                if GetRecordingStat() == 1: # If camera is capturing
                    SetEndRecordingTimer(60)    # Onset a timer to finish video recording after 60 frames (correspond about 2sec) from now

                # Add summary of results into the result file
                if CorrectNum > 0 or IncorrectNum > 0:
                    CorrectRate = int(CorrectNum * 100.0 / TrialNum)
                Writer_TouchEventTxt.write('TotalNum:' + str(TrialNum) + '  CorrectNum:' + str(CorrectNum) + '  IncorrectNum:' + str(IncorrectNum) + '  CorrectRate:' + str(CorrectRate) + '%\n')
                Writer_TouchEventTxt.write('SessionStartTime: ' + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()) + "\n")
                Writer_TouchEventTxt.write('SessionEndTime: ' + str(TimeNow.month) + '/' + str(TimeNow.day) + ' ' + str(TimeNow.hour) + ':' + str(TimeNow.minute) + ':' + str(TimeNow.second + (TimeNow.microsecond // 1000) / 1000) + "\n")
                Writer_TouchEventTxt.write('TaskDuration(sec): ' + str(TaskDur) + "\n")
                # Add experimental conditions into the result file
                Writer_TouchEventTxt.write('MaxCorrectNum: '+str(MaxCorrectNum)+"\n")
                Writer_TouchEventTxt.write('MaxTrialNum: ' + str(MaxTrialNum) + "\n")
                Writer_TouchEventTxt.write('TimeLimit: ' + str(TimeLimit) + "\n")
                Writer_TouchEventTxt.write('PunishDur: ' + str(TimeLimit) + "\n")
                Writer_TouchEventTxt.write('LickDur: ' + str(LickDur)+"\n")
                Writer_TouchEventTxt.write('NextTask: ' + str(NextTask) + "\n")
                Writer_TouchEventTxt.write('NextTaskTh: ' + str(NextTaskTh) + "\n")
                Writer_TouchEventTxt.write('PanelType: ' + PanelType + "\n")
                Writer_TouchEventTxt.write('WaterCueType: ' + WaterCueType + "\n")
                Writer_TouchEventTxt.write('AwsOn: ' + AwsOn + "\n")
                Writer_TouchEventTxt.write('RecordFPS: ' + str(GetRecordFps()) + "\n")  # Recorded frame number per second
                Writer_TouchEventTxt.write(GetRoiSensitivity() + "\n")  # Settings of each ROI
                Writer_TouchEventTxt.write(GetServoAngle() + "\n")  # Set angles of each servo

                Writer_TouchEventTxt.close()    # Close the text exporter for the result file
                Writer_TouchEventCsv.close()
                EndLickRecording()  # End lick log recording

                SendMail(DeviceNameVar.get()+' finished task '+str(GetTaskID())+'. TrialNum:'+str(TrialNum)+' Correct:'+str(CorrectNum)+' Incorrect:'+str(IncorrectNum)+' Rate:'+str(CorrectRate)+'% Dur:'+str(round(Timer_GetSec(5) / 60,1))+' min','The task is finished.') # Send a email (correct number and task duration are added to email title)

                if IsHousingAnalysis == 1 and Phase2 == -1:  # If it is housing analysis
                    if CorrectRate >= NextTaskTh:  # If the score exceed the criteria to switch to the next task
                        SwitchTask(NextTask)  # Onset the task switching trigger
                        print("Task was switched to task#" + str(NextTask) + "  " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

                if IsHousingAnalysis == 0:
                    RoofLightOn()

                Phase = 1  # Go back to the task-waiting phase
                Phase2 = 0
                Phase2_Init = 0

            SetDispVariable(0, 'Phase2', str(Phase2))  # Display "Phase2" value on the bottom of main window
    return

def Task93():   # Test task 4 (Explanation material: Lever task)
    global Phase
    Phase0_Init = 0
    Phase1_Init = 0
    Phase2_Init = 0
    while EndFlag == 0:
        OperantHouseUpdate()    # Run house keeping function (This must be executed once per frame)

        if GetBackButtonStat()==1:    # If "Back" button is clicked
            break   # Back to the task select phase
        if Phase == 0:  # Parameter inputs
            if Phase0_Init == 0:    # Make GUI for the setting of the parameters for this task
                RemoveMainRightWidget() # Remove task buttons
                PutStartBackButton()    # Put "start" and "back" buttons

                ColumnWidth = 14    # Width of input columns
                Row = 0
                Column = 0
                mMaxCorrectNum = ttk.Label(MainWindowRightFrame, text='MaxCorrectNum', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)    # Put label
                MaxCorrectNumVar = IntVar(MainWindowRoot)  # Declare a variable for input column
                iMaxCorrectNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxCorrectNumVar, width=ColumnWidth).grid(row=Row + 1, column=Column)  # Create input column and link it with the variable
                Column += 1
                mMaxTrialNum = ttk.Label(MainWindowRightFrame, text='MaxTrialNum', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                MaxTrialNumVar = IntVar(MainWindowRoot)  # Declare a variable for input column
                iMaxTrialNum = ttk.Entry(MainWindowRightFrame, textvariable=MaxTrialNumVar, width=ColumnWidth).grid(row=Row + 1, column=Column)
                Column += 1
                mTimeLimit = ttk.Label(MainWindowRightFrame, text='TimeLimit(min)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                TimeLimitVar = DoubleVar(MainWindowRoot)
                iTimeLimit = ttk.Entry(MainWindowRightFrame, textvariable=TimeLimitVar, width=ColumnWidth).grid(row=Row + 1, column=Column)
                Column += 1
                mPunishDur = ttk.Label(MainWindowRightFrame, text='PunishDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                PunishDurVar = DoubleVar(MainWindowRoot)
                iPunishDur = ttk.Entry(MainWindowRightFrame, textvariable=PunishDurVar, width=ColumnWidth).grid(row=Row + 1, column=Column)
                Column += 1
                mLickDur = ttk.Label(MainWindowRightFrame, text='LickDur(s)', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)
                LickDurVar = DoubleVar(MainWindowRoot)
                iLickDur = ttk.Entry(MainWindowRightFrame, textvariable=LickDurVar, width=ColumnWidth).grid(row=Row + 1, column=Column)
                Column += 1
                mNextTask = ttk.Label(MainWindowRightFrame, text='NextTask#', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # The task number indicated here will be the next task if the correct rate exceeds "NextTaskTh"
                NextTaskVar = IntVar(MainWindowRoot)
                iNextTask = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskVar, width=ColumnWidth).grid(row=Row + 1, column=Column)
                Column += 1
                mNextTaskTh = ttk.Label(MainWindowRightFrame, text='NextTaskTh%', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)   # Correct rate threshold to switch to the next task
                NextTaskThVar = DoubleVar(MainWindowRoot)
                iNextTaskTh = ttk.Entry(MainWindowRightFrame, textvariable=NextTaskThVar, width=ColumnWidth).grid(row=Row + 1, column=Column)

                Row += 2  # Begin a new line
                Column = 0

                mCorrectPos = ttk.Label(MainWindowRightFrame, text='CorrectPos', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # Position of correct lever
                CorrectPosVar = StringVar(MainWindowRightFrame)
                tCorrectPos = OptionMenu(MainWindowRightFrame, CorrectPosVar, "Left", "Right").grid(row=Row + 1, column=Column, sticky=W)
                Column += 1
                mWaterCueType = ttk.Label(MainWindowRightFrame, text='WaterCueType', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # If chose blink, reward cue will blink
                WaterCueTypeVar = StringVar(MainWindowRightFrame)
                tWaterCueType = OptionMenu(MainWindowRightFrame, WaterCueTypeVar, "Normal", "Blink").grid(row=Row + 1, column=Column, sticky=W)
                Column += 1
                mAwsOn = ttk.Label(MainWindowRightFrame, text='AWS', width=ColumnWidth).grid(row=Row, column=Column, sticky=W)  # If ON, complemental water supply is applied after end of each session
                AwsOnVar = StringVar(MainWindowRoot)
                tAwsOn = OptionMenu(MainWindowRightFrame, AwsOnVar, "ON", "OFF").grid(row=Row + 1, column=Column, sticky=W)

                Str = "ParametersForTask" + str(GetTaskID())
                if os.path.exists(Str + '/MaxCorrectNum.dat') == True:  # If save file named "MaxCorrectNum.dat" exist:
                    with open(Str + '/MaxCorrectNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxCorrectNumVar.set(pickle.load(PickleInst[GetTaskID()]))  # Assign loaded data into the variable of this program
                else:  # If save file doesn't exist
                    MaxCorrectNumVar.set(80)  # Assign 80 into the variable

                if os.path.exists(Str + '/MaxTrialNum.dat') == True:
                    with open(Str + '/MaxTrialNum.dat', 'rb') as PickleInst[GetTaskID()]:
                        MaxTrialNumVar.set(pickle.load(PickleInst[GetTaskID()]))
                else:
                    MaxTrialNumVar.set(110)

                if os.path.exists(Str + '/TimeLimit.dat') == True:
                    with open(Str + '/TimeLimit.dat', 'rb') as PickleInst[GetTaskID()]:
                        TimeLimitVar.set(pickle.load(PickleInst[GetTaskID()]))
                else:
                    TimeLimitVar.set(600)

                if os.path.exists(Str + '/PunishDur.dat') == True:
                    with open(Str + '/PunishDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        PunishDurVar.set(pickle.load(PickleInst[GetTaskID()]))
                else:
                    PunishDurVar.set(10)

                if os.path.exists(Str + '/LickDur.dat') == True:
                    with open(Str + '/LickDur.dat', 'rb') as PickleInst[GetTaskID()]:
                        LickDurVar.set(pickle.load(PickleInst[GetTaskID()]))
                else:
                    LickDurVar.set(2)

                if os.path.exists(Str + '/NextTask.dat') == True:
                    with open(Str + '/NextTask.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskVar.set(93)  # Default value

                if os.path.exists(Str + '/NextTaskTh.dat') == True:
                    with open(Str + '/NextTaskTh.dat', 'rb') as PickleInst[GetTaskID()]:
                        NextTaskThVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    NextTaskThVar.set(80)  # Default value

                if os.path.exists(Str + '/CorrectPos.dat') == True:
                    with open(Str + '/CorrectPos.dat', 'rb') as PickleInst[GetTaskID()]:
                        CorrectPosVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    CorrectPosVar.set('Left')  # Default value

                if os.path.exists(Str + '/WaterCueType.dat') == True:
                    with open(Str + '/WaterCueType.dat', 'rb') as PickleInst[GetTaskID()]:
                        WaterCueTypeVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    WaterCueTypeVar.set('Blink')  # Default value

                if os.path.exists(Str + '/AwsOn.dat') == True:
                    with open(Str + '/AwsOn.dat', 'rb') as PickleInst[GetTaskID()]:
                        AwsOnVar.set(pickle.load(PickleInst[GetTaskID()]))  # Load
                else:
                    AwsOnVar.set('ON')  # Default value

                RemoveAllRoiGui()
                PutRoiGui(19, 0, 0, 1)  # Put setting GUI of the indicated ROI on ROI window (ROI number, Detection mode, Threshold direction, ShowSymbol or not)

                RemoveAllDigitalOutGui()    # Remove all GUIs on the Digital out window
                PutDigitalOutGui(10)    # Put the digital output GUI for channel 10 on Digital ouput window
                PutDigitalOutGui(12)
                PutDigitalOutGui(13)

                DigitalInOn(7)  # Set the indicated channel as Digital input channel (Receive input from the lever module)
                DigitalInOn(8)

                RemoveAllServoGui() # Remove all GUI on the Servo GUI
                PutServoGui(3)  # Put a servo GUI for channel 3 on the Servo GUI
                PutServoGui(5)
                PutServoGui(6)

                Phase0_Init = 1 # Set a flag which indicating phase0 initialization has done

        if GetSaveTrgStat() == 1:    # If save trigger is activated
            # Parameters will be saved into a folder named "ParametersForTask90"
            Str="ParametersForTask"+str(GetTaskID())   # Assign save folder path
            if os.path.exists(Str) == False:    # If save folder doesn't exist
                os.mkdir(Str)   # Create the folder
            with open(Str+'/MaxCorrectNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxCorrectNumVar.get(),PickleInst[GetTaskID()])     # Save a value of "MaxCorrectNumVar" as "MaxCorrectNum.dat" file

            with open(Str+'/MaxTrialNum.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(MaxTrialNumVar.get(),PickleInst[GetTaskID()])

            with open(Str+'/TimeLimit.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(TimeLimitVar.get(),PickleInst[GetTaskID()])

            with open(Str+'/PunishDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(PunishDurVar.get(), PickleInst[GetTaskID()])

            with open(Str+'/LickDur.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(LickDurVar.get(), PickleInst[GetTaskID()])

            with open(Str + '/NextTask.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskVar.get(), PickleInst[GetTaskID()])

            with open(Str+'/NextTaskTh.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(NextTaskThVar.get(), PickleInst[GetTaskID()])

            with open(Str+'/CorrectPos.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(CorrectPosVar.get(), PickleInst[GetTaskID()])

            with open(Str+'/WaterCueType.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(WaterCueTypeVar.get(), PickleInst[GetTaskID()])

            with open(Str+'/AwsOn.dat', 'wb') as PickleInst[GetTaskID()]:
                pickle.dump(AwsOnVar.get(), PickleInst[GetTaskID()])

        if Phase == 1:  # Waiting phase (Task will start when the set time arrives)
            if Phase1_Init == 0: # If the initialization for phase1 has not done
                PutPreTaskButton()  # Put "StartNow" and "Back" button on Main window
                mStatusVar = StringVar(MainWindowRoot)  # Create a variable for status display
                mStatus = ttk.Label(MainWindowRightFrame, textvariable=mStatusVar)  # Create label object and link it with Main window
                mStatus.place(x=10, y=0)    # Place label object on the Main window
                mOngoingResultVar = StringVar(MainWindowRoot)   # Create a variable for progress display
                Phase1_Init = 1 # Flat that phase1 has done
            mStatusVar.set('Test4 task (' + str(GetTaskID()) + ')    Waiting...')    # Show current status of the Operant House
            if IsStartTime() == 1:  # Check whether task start time arrives
                StartNow()  # Start task (Phase number will be "2")

        if Phase == 2:  # If it is during task
            if Phase2_Init == 0: # Initialization of the task
                PutEndTaskNowButton()   # Put "TaskEnd" button on Main window
                mStatusVar.set('Test4 task (' + str(GetTaskID()) + ')    Start time ' + str(TaskStartedMonth) + '/' + str(TaskStartedDay) + ' ' + str(TaskStartedHour) + ':' + str(TaskStartedMinute) + '    Running')    # Assign latest information about current task into "mStatusVar"
                mOngoingResult = ttk.Label(MainWindowRightFrame, textvariable=mOngoingResultVar)
                mOngoingResult.place(x=10, y=18)

                # Assign task parameter values in StringVars into integer or string variable (to make the cord easeir to read)
                MaxCorrectNum = int(MaxCorrectNumVar.get())   # Get the value of "MaxCorrectNumVar" and convert it from string to integer and assign into variable named "MaxCorrectNum"
                MaxTrialNum = int(MaxTrialNumVar.get())
                TimeLimit = float(TimeLimitVar.get())
                PunishDur = float(PunishDurVar.get())
                LickDur = float(LickDurVar.get())
                NextTask = int(NextTaskVar.get())
                NextTaskTh = float(NextTaskThVar.get())
                CorrectPos = CorrectPosVar.get()
                WaterCueType = WaterCueTypeVar.get()
                AwsOn = AwsOnVar.get()

                # Declar local variables for this task
                TrialNum = 0    # Current trial number
                CorrectNum = 0  # Current correct trial number
                IncorrectNum = 0    # Current incorrect trial number
                CorrectRate = 0.0   # Current correct rate
                TaskDur = 0  # This will keep the elapsed time during of task
                NowDrinking = 0 # Use as trigger
                AWS_Latency = 20    # Latency to start AWS (sec)

                StartRecording()  # Start camera capture / TTL signal output
                StartLickRecording()  # Start an entry of lick log
                LightCycleControlOff()  # Deactivate automatic Light/Dark cycle illumination
                RoofLightOff()  # Turn off the lights on roof (Digital output Ch13)
                InfraredLightOn()   # Turn on the infrared LED illumination (Digital output Ch12)
                if WaterCueType == 'Normal':
                    DigitalOutOn(10)    # Turn on cue LED connected to Ch10
                if WaterCueType == 'Blink':
                    DigitalOutBlinkOn(10)   # Start blinking of cue LED connected to Ch10
                ServoPosInside(3)   # Change the angle of water arm servo connected to Ch3 to inside position

                Writer_TouchEventTxt = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.txt", 'w')  # Initialize the text exporter for a result file
                Writer_TouchEventTxt.write('TrialNum\tResult\t\t\tyyyy/mm/dd\th:m\ts\n')  # Write item name on the result file
                Writer_TouchEventCsv = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(GetTaskID()) + " Touch.csv", 'w')
                print("Task #" + str(GetTaskID()) + " is started at " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))  # Enter the start time in the console window of Pycharm

                Timer_Start(5)  # Start a timer #5 to measure the duration of the task
                Phase2 = 2  # Start task from the reward phase
                Phase2_Init = 1 # Flag indicating that initialization of Phase2 has done

            if Phase2 == 0:   # Initiation of new trial
                TaskDur = Timer_GetSec(5)
                ServoPosInside(5)   # Insert the indicated lever
                ServoPosInside(6)
                Phase2 = 1

            if Phase2 == 1:   # Lever choice
                LeftLeverStat = DetectLeverPress(7) # Return 1 if current in digital input Ch7 is detected (Check input from left lever)
                RightLeverStat = DetectLeverPress(8) # Return 1 if current in digital input Ch8 is detected (Check input from right lever)
                if LeftLeverStat==1 or RightLeverStat==1: # If mouse touches the panel
                    TrialNum += 1
                    if CorrectPos=="Left" and LeftLeverStat==1 or CorrectPos=="Right" and RightLeverStat==1:    # If touched correct lever
                        ServoPosInside(3)    # Move the water nozzle into inside position
                        if WaterCueType == 'Normal':
                            DigitalOutOn(10)  # Turn on cue LED connected to Ch10
                        if WaterCueType == 'Blink':
                            DigitalOutBlinkOn(10)  # Start blinking of cue LED connected to Ch10
                        ServoPosOutside(5)  # Pull the indicated lever back
                        ServoPosOutside(6)
                        NowDrinking = 0
                        CorrectNum += 1     # Increase the number of correct response
                        Writer_TouchEventTxt.write(str(TrialNum)+'\tLeverPressed(Correct)\t'+ str(TimeNow.year)+"/"+str(TimeNow.month)+"/"+str(TimeNow.day)+"\t"+str(TimeNow.hour)+":"+str(TimeNow.minute)+"\t"+str(TimeNow.second)+"."+str(TimeNow.microsecond//1000)+"\n") # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',1,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000)+"\n")  # Write the response on the csv file
                        Phase2 = 2  # Start reward phase

                    if CorrectPos=="Left" and RightLeverStat==1 or CorrectPos=="Right" and LeftLeverStat==1:    # If touched incorrect lever
                        ServoPosOutside(3)    # Move the water nozzle into inside position
                        ServoPosOutside(5)  # Pull the indicated lever back
                        ServoPosOutside(6)
                        RoofLightOn()   # Turn on the ceiling illumination
                        IncorrectNum += 1     # Increase the number of correct response
                        Writer_TouchEventTxt.write(str(TrialNum)+'\tLeverPressed(Incorrect)\t'+ str(TimeNow.year)+"/"+str(TimeNow.month)+"/"+str(TimeNow.day)+"\t"+str(TimeNow.hour)+":"+str(TimeNow.minute)+"\t"+str(TimeNow.second)+"."+str(TimeNow.microsecond//1000)+"\n") # Write the response on the text file
                        Writer_TouchEventCsv.write(str(TrialNum) + ',2,' + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond//1000)+"\n")  # Write the response on the csv file
                        Timer_Start(0)  # Start punishment timer
                        Phase2 = 3  # Start punish phase
                    mOngoingResultVar.set('CorrectNum: ' + str(CorrectNum) + '  IncorrectNum: ' + str(IncorrectNum) + '  TrialNum: ' + str(TrialNum))

                if Timer_GetSec(5) >= TimeLimit * 60:   # If time limit of the task comes
                    TaskDur = Timer_GetSec(5)
                    print("Time limit elapsed")
                    Timer_End(5)    # Stop the timer
                    Phase2 = 5

            if Phase2 == 2:  # Reward phase
                if DetectRoiNosepoke() == 19 and NowDrinking == 0:    # If the mouse initiates nose poking
                    NowDrinking = 1
                    Timer_Start(0)  # Start lick timer
                if NowDrinking == 1:    # If the nose poke has begun
                    if Timer_GetSec(0) >= LickDur:   # If the nosepoke duration exceeds the lick duration
                        Timer_End(0) # End timer for measuring lick duration
                        ServoPosMiddle(3)   # Move water nozzle back to the middle position
                        DigitalOutOff(10)   # Turn off the cue LED
                        NowDrinking = 0
                        Phase2 = 4  # Go to After trial phase

            if Phase2 == 3:  # Punishment phase
                if Timer_GetSec(0) >= PunishDur:  # If punishment time is passed
                    Timer_End(0)  # End punishment timer1
                    RoofLightOff()
                    ServoPosMiddle(3)  # Move water nozzle to the intermediate position
                    Phase2 = 4  # Go to After trial phase

            if Phase2 == 4:  # After trial phase
                if CorrectNum < MaxCorrectNum and TrialNum < MaxTrialNum:  # If the touch number doesn't exceed the maximum number
                    Phase2 = 0
                if CorrectNum >= MaxCorrectNum or TrialNum >= MaxTrialNum:  # If the touch number exceeds the maximum number
                    TaskDur = Timer_GetSec(5)  # Keep the task time
                    Phase2 = 5

            if Phase2 == 5:
                ServoPosOutside(5)  # Pull the indicated lever back
                ServoPosOutside(6)
                if CorrectNum < MaxCorrectNum and AwsOn == 'ON':  # If mouse didn't achieved the max correct response
                    Timer_Start(0)
                    Phase2 = 6
                if CorrectNum == MaxCorrectNum or AwsOn == 'OFF':  # If mouse achieved the max correct response
                    Phase2 = -1

            if Phase2 == 6:  # Wait until complemental water supply is started
                if Timer_GetSec(0) >= AWS_Latency:  # If it past indicated latency to start complemental water supply
                    Timer_End(0)
                    ArbitaryWaterSupplyDur = (MaxCorrectNum - CorrectNum) * LickDur * 1000  # Calculate the duration of complemental water supply
                    if WaterCueType == 'Normal':
                        StartArbitaryWaterSupply(3, 10, 0, ArbitaryWaterSupplyDur)  # Start complemental water supply
                    if WaterCueType == 'Blink':
                        StartArbitaryWaterSupply(3, 10, 1, ArbitaryWaterSupplyDur)
                    print("Arbitrary water supply start")
                    Phase2 = 7  # Start AWS

            if Phase2 == 7: # Keep checking until complemental water supply is finished
                if GetArbitaryWaterSupplyStat() == 1:  # If the complemental water supply is finished
                    Phase2 = -1

            if Phase2 == -1 or GetEndTaskNowButtonStat() == 1:  # If the flag is set to finish the task
                LightCycleControlOn()   # Activate automatic light/dark cycle
                ServoPosMiddle(3)   # Moze servo nozzle into middle position
                ServoPosOutside(5)  # Pull the indicated lever back
                ServoPosOutside(6)
                InfraredLightOff()  # Turn off the infrared LED
                if GetRecordingStat() == 1: # If camera is capturing
                    SetEndRecordingTimer(60)    # Onset a timer to finish video recording after 60 frames (correspond about 2sec) from now

                # Add summary of results into the result file
                if CorrectNum > 0 or IncorrectNum > 0:
                    CorrectRate = int(CorrectNum * 100.0 / TrialNum)
                Writer_TouchEventTxt.write('TotalNum:' + str(TrialNum) + '  CorrectNum:' + str(CorrectNum) + '  IncorrectNum:' + str(IncorrectNum) + '  CorrectRate:' + str(CorrectRate) + '%\n')
                Writer_TouchEventTxt.write('SessionStartTime: ' + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()) + "\n")
                Writer_TouchEventTxt.write('SessionEndTime: ' + str(TimeNow.month) + '/' + str(TimeNow.day) + ' ' + str(TimeNow.hour) + ':' + str(TimeNow.minute) + ':' + str(TimeNow.second + (TimeNow.microsecond // 1000) / 1000) + "\n")
                Writer_TouchEventTxt.write('TaskDuration(sec): ' + str(TaskDur) + "\n")
                # Add experimental conditions into the result file
                Writer_TouchEventTxt.write('MaxCorrectNum: '+str(MaxCorrectNum)+"\n")
                Writer_TouchEventTxt.write('MaxTrialNum: ' + str(MaxTrialNum) + "\n")
                Writer_TouchEventTxt.write('TimeLimit: ' + str(TimeLimit) + "\n")
                Writer_TouchEventTxt.write('PunishDur: ' + str(TimeLimit) + "\n")
                Writer_TouchEventTxt.write('LickDur: ' + str(LickDur)+"\n")
                Writer_TouchEventTxt.write('NextTask: ' + str(NextTask) + "\n")
                Writer_TouchEventTxt.write('NextTaskTh: ' + str(NextTaskTh) + "\n")
                Writer_TouchEventTxt.write('CorrectPos: ' + CorrectPos + "\n")
                Writer_TouchEventTxt.write('WaterCueType: ' + WaterCueType + "\n")
                Writer_TouchEventTxt.write('AwsOn: ' + AwsOn + "\n")
                Writer_TouchEventTxt.write('RecordFPS: ' + str(GetRecordFps()) + "\n")  # Recorded frame number per second
                Writer_TouchEventTxt.write(GetRoiSensitivity() + "\n")  # Settings of each ROI
                Writer_TouchEventTxt.write(GetServoAngle() + "\n")  # Set angles of each servo

                Writer_TouchEventTxt.close()    # Close the text exporter for the result file
                Writer_TouchEventCsv.close()
                EndLickRecording()  # End lick log recording

                SendMail(DeviceNameVar.get()+' finished task '+str(GetTaskID())+'. TrialNum:'+str(TrialNum)+' Correct:'+str(CorrectNum)+' Incorrect:'+str(IncorrectNum)+' Rate:'+str(CorrectRate)+'% Dur:'+str(round(Timer_GetSec(5) / 60,1))+' min','The task is finished.') # Send a email (correct number and task duration are added to email title)

                if IsHousingAnalysis == 1 and Phase2 == -1:  # If it is housing analysis
                    if CorrectRate >= NextTaskTh:  # If the score exceed the criteria to switch to the next task
                        SwitchTask(NextTask)  # Onset the task switching trigger
                        print("Task was switched to task#" + str(NextTask) + "  " + str(GetTaskStartedMonth()) + '/' + str(GetTaskStartedDay()) + ' ' + str(GetTaskStartedHour()) + ':' + str(GetTaskStartedMinute()) + ':' + str(GetTaskStartedSecond()))

                if IsHousingAnalysis == 0:
                    RoofLightOn()

                Phase = 1  # Go back to the task-waiting phase
                Phase2 = 0
                Phase2_Init = 0

            SetDispVariable(0, 'Phase2', str(Phase2))  # Display "Phase2" value on the bottom of main window
    return




def StartRecording():   # Start camera caputring
    global NowRecording, NextShatterTime, SendingTtl, ElapsedTime, ElapsedTimePerFrame, TtlPreTime, TtlCurrTime, TtlPreQuotient, TtlCurrQuotient, TtlCurrRemainder, TtlSquareElapsedTime, TtlCnt, TtlIsFirst, TtlPower, DigitalOut, Writer_TtlLogCsv, VideoWriter, MovieWidth, MovieHeight, RecordFps, PlayBackFps
    if NowRecording==0:
        NowRecording = 1
        if RaspberryMode == 0:
            #fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')  # Define the codec and create VideoWriter object
            fourcc = cv2.VideoWriter_fourcc(*'XVID')  # Define the codec and create VideoWriter object
        if RaspberryMode == 1:
            fourcc = cv2.VideoWriter_fourcc('m','p','4','v')  # Define the codec and create VideoWriter object
        MovieWidth = int(MovieWidthVar.get())
        MovieHeight = int(MovieHeightVar.get())
        VideoWriter = cv2.VideoWriter(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m" + str(TimeNow.second) + "s Task" + str(Task) + ".avi",fourcc, PlayBackFps, (MovieWidth,MovieHeight)) #Prepare to save movie
        SendingTtl = 1
        ElapsedTime = 0
        ElapsedTimePerFrame = 0
        TtlPreTime = TimeNow.day*24*60*60*1000 + TimeNow.hour*60*60*1000 + TimeNow.minute*60*1000 + TimeNow.second*1000 + (TimeNow.microsecond//1000)
        TtlCurrTime = TimeNow.day*24*60*60*1000 + TimeNow.hour*60*60*1000 + TimeNow.minute*60*1000 + TimeNow.second*1000 + (TimeNow.microsecond//1000)
        NextShatterTime=0
        TtlPreQuotient = 0
        TtlCurrQuotient = 0
        TtlCurrRemainder = 0
        TtlSquareElapsedTime = 0
        TtlCnt = 0
        TtlIsFirst = 1
        TtlPower = -1
        DigitalOut[11] = 0
        Writer_TtlLogCsv = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(Task) + " TTL.csv", 'w')  # Initialize the text exporter
        Writer_TtlLogCsv.write("No,Hour,Min,Sec\n")  # # Write the timing of TTL onset and offset
        RecordFps=int(RecordFpsVar.get())
        PlayBackFps = int(PlayBackFpsVar.get())
        print("RecordFPS: "+str(RecordFps))
        print("PlayBackFps: "+str(PlayBackFps))
    return




def SetEndRecordingTimer(FrameNum): # Start a timer for stopping camera caputring
    global EndRecordTimerOn, EndRecordTimerCnt
    EndRecordTimerOn = 1
    EndRecordTimerCnt=FrameNum
    return
def EndRecording(): # Stop camera caputring
    global NowRecording, SendingTtl, Writer_TtlLogCsv,TtlPower, WinApiForCamera, VideoCapture, CameraID, TargetFps, VideoWriter, mouseData
    if NowRecording==1:
        NowRecording = 0
        SendingTtl = 0
        TtlPower = -1
        VideoWriter.release()   #Close video save function
        VideoCapture.release()  #Close video capture function
        cv2.destroyAllWindows() #Close window for opencv (Shows captured video)
        Writer_TtlLogCsv.close()

        #Re-create new opencv window
        if RaspberryMode==0:
            #VideoCapture = cv2.VideoCapture(CameraID)

            if WinApiForCamera == 0:
                VideoCapture = cv2.VideoCapture(CameraID, cv2.CAP_DSHOW)  # Make video capture  # VideoCapture = cv2.VideoCapture(1, cv2.CAP_DSHOW)       #Make video capture
            if WinApiForCamera == 1:
                VideoCapture = cv2.VideoCapture(CameraID, cv2.CAP_MSMF)  # Make video capture  # VideoCapture = cv2.VideoCapture(0)
        if RaspberryMode==1:
            VideoCapture = cv2.VideoCapture(CameraID, cv2.CAP_V4L2)
        VideoCapture.set(cv2.CAP_PROP_FPS, TargetFps)  # Set FPS of camera capturing
        # VideoCapture.set(cv2.CAP_PROP_POS_FRAMES, 0);  # Useless
        # VideoCapture.set(cv2.CAP_PROP_BUFFERSIZE, 3);  # Useless

        cv2.namedWindow("CameraWindow")  # Make video window
        cv2.moveWindow("CameraWindow", CameraWindowPosX, CameraWindowPosY)
        mouseData = mouseParam("CameraWindow")  # Instantiate class for get mouse cursor coordinates of camera window
    return

def Timer_Start(i): # Start general propose timer
    global TimerRunning, TimerCounter, TimerSec, TimerPreTime
    TimerRunning[i] = 1
    TimerCounter[i] = 0
    TimerSec[i] = 0
    TimerPreTime[i] = TimeNow.microsecond // 100000
    return
def Timer_End(i):   # End general propose timer
    global TimerRunning
    TimerRunning[i] = 0
    return
def Timer_Reset(i):
    global TimerRunning, TimerCounter, TimerSec, TimerPreTime
    TimerRunning[i] = 0
    TimerCounter[i] = 0
    TimerSec[i] = 0
    TimerPreTime[i] = TimeNow.microsecond // 100000
def Timer_GetSec(id):
    global TimerSec
    return TimerSec[id]
def GetTimerStat(id):   #
    global TimerRunning
    return TimerRunning[id]


def DetectRoiNosepoke(): # Return ID of the touching ROI (Return -1 if no ROI detect nosepoke, Return 19 if water slit ROI detects nosepoke, Retern panel ID if panel ROI detects nosepoke)
    global TouchX, TouchY, PanelULX, PanelULY, PanelBRX, PanelBRY, Task, TouchDetectionOnCnt, MaxPanelNum,  RoiHitNum, RoiDetect, Roi1Y, Roi2Y, ManualRoiDetectionID, ManualRoiDetectionCnt,TouchDetectSensorType, RoiDetectNum
    TouchedPanelID = -1
    ChampTopHeight=0
    ChampBottomHeight = 0
    ChampHitNum = 0
    ChampRoiID = -1
    RoiDetectNum = 0
    for i in range(0, MaxPanelNum): # Determine which panel is nose poked if multiple panels detect nosepokes.
        if RoiUsed[Task][i]==1:
            if RoiDetect[Task][i]==1:
                RoiDetectNum+=1
                Trg=0
                if ChampTopHeight < Roi2Y[Task][i]:   # If this panel is 1 floor higher than champ panel
                    Trg=1
                if ChampTopHeight >= Roi2Y[Task][i] and ChampBottomHeight <= Roi1Y[Task][i] and Trg==0:  # If level of this panel is same as champ panel
                    if ChampHitNum < RoiHitNum[Task][i]:    # If this panel has more hit
                        Trg=1
                if Trg==1:
                    ChampTopHeight = Roi1Y[Task][i]
                    ChampBottomHeight = Roi2Y[Task][i]
                    ChampHitNum = RoiHitNum[Task][i]
                    ChampRoiID = i
                    #    break   # Water slit is chosen because this ROI is given priority
    TouchedPanelID = ChampRoiID

    if TouchDetectSensorType == 1:
        if TouchDetectionOnCnt > 0:
            for i in range(0, MaxPanelNum):
                if TouchX >= PanelULX[Task][i] and TouchY >= PanelULY[Task][i] and TouchX <= PanelBRX[Task][i] and TouchY <= PanelBRY[Task][i]:
                    TouchedPanelID=i
                    print("Panel "+str(i)+" is touched.")
                    break
        TouchDetectionOnCnt = 0

    return TouchedPanelID

def DetectHoleTouch(Num):   # Return number of the infrared sensor of the hole (not used now)
    global DebugWithoutArduinoMode
    Value=1000
    TouchedHoleID = -1
    if Num==0:
        if DebugWithoutArduinoMode == 0:
            ser.flushInput()  # Clear input buffer from arduino
            Value=int(ser.readline().decode("utf-8").strip('\n').strip('\r'))  # Read the input value of the infrared sensor (Work when combined with "Serial conection with python 4")
        if Value < 500:
            TouchedHoleID=0
        else:
            TouchedHoleID=-1
    return TouchedHoleID

def MeasureDistanceSquare(X1,Y1,X2,Y2):  # general-purpose
    Distance = ((X2 - X1) * (X2 - X1)) + ((Y2 - Y1) * (Y2 - Y1))
    return Distance
def MeasureDistance(X1,Y1, X2,Y2):  # general-purpose
    Distance = math.sqrt(((X2 - X1) * (X2 - X1)) + ((Y2 - Y1) * (Y2 - Y1)))
    return Distance

def ToggleDigitalOut(Ch):    # Function of the LED test button
    global DigitalOut, DigitalOutGuiUpdateTrg, LightCycleControl
    Trg=0
    if DigitalOut[Ch]==0:
        DigitalOutOn(Ch)
        Trg=1
    if DigitalOut[Ch]==1 and Trg==0:
        DigitalOutOff(Ch)
    LightCycleControl = 0
    DigitalOutGuiUpdateTrg = 1
    return

def ToggleManualPanel():    # Shows all panels in the task
    global ManualPanelOnTrg, Task, MaxPanelNum, ManualPanelRef
    Trg=0
    if ManualPanelOnTrg==0:
        ManualPanelOnTrg=1
        for i in range(MaxPanelNum):
            if PanelULX[Task][i] != 0:  # If this panel is used in the current task
                ManualPanelRef[i] = CanvasTouchWindow.create_rectangle(PanelULX[Task][i], PanelULY[Task][i], PanelBRX[Task][i], PanelBRY[Task][i], fill='white')  # Create panel
        Trg=1
    if ManualPanelOnTrg==1 and Trg==0:
        ManualPanelOnTrg = 0
        for i in range(MaxPanelNum):
            if ManualPanelRef[i]:  # If this panel is used in the current task
                CanvasTouchWindow.delete(ManualPanelRef[i])
    return

def ToggleManualBlinkPanel():
    global ManualBlinkPanelOnTrg, Task, MaxPanelNum, ManualBlinkPanelRef
    Trg=0
    if ManualBlinkPanelOnTrg==0: # If manual blink panels weren't shown
        ManualBlinkPanelOnTrg=1
        for i in range(MaxPanelNum):
            if PanelULX[Task][i] != 0:  # If this panel is used in the current task
                ManualBlinkPanelRef[i] = CanvasTouchWindow.create_rectangle(PanelULX[Task][i], PanelULY[Task][i], PanelBRX[Task][i], PanelBRY[Task][i], fill='white')  # Create panel
        Trg = 1
        print("Manual blink panels are created")
    if ManualBlinkPanelOnTrg == 1 and Trg == 0:
        ManualBlinkPanelOnTrg = 0
        for i in range(MaxPanelNum):
            if ManualBlinkPanelRef[i]:  # If this panel is used in the current task
                CanvasTouchWindow.delete(ManualBlinkPanelRef[i])
        print("Manual blink panels are deleted")
    return

def ButtonAWS():    #
    global ButtonAWS_On
    ServoPosInside(3)
    DigitalOutOn(10)
    RoofLightOff()
    ButtonAWS_Dur=0
    if ButtonAWS_DurVar.get()!="":
        ButtonAWS_Dur=int(ButtonAWS_DurVar.get())
        StartArbitaryWaterSupply(3, 10, 0, ButtonAWS_Dur*1000)
    ButtonAWS_On=1
    return
def ButtonAWS_Blink():
    global ButtonAWS_On
    ServoPosInside(3)
    DigitalOutBlinkOn(10)
    RoofLightOff()
    ButtonAWS_Dur = 0
    if ButtonAWS_DurVar.get().isdigit():  # Check whether the string is digit
        ButtonAWS_Dur = int(ButtonAWS_DurVar.get())
        StartArbitaryWaterSupply(3, 10, 1, ButtonAWS_Dur * 1000)
    ButtonAWS_On = 1
    return
def motion(event):  # Get mouse coordinate in tkinter window
    global MxTk, MyTk, PreMxTk, PreMyTk
    PreMxTk = MxTk
    PreMyTk = MyTk
    MxTk = event.x
    MyTk = event.y
    #print(str(MxTk) + "," + str(MyTk))

def create_message(from_addr, to_addr, bcc_addrs, subject, body):   # For email
    msg = MIMEText(body)
    msg['Subject'] = subject
    msg['From'] = from_addr
    msg['To'] = to_addr
    msg['Bcc'] = bcc_addrs
    msg['Date'] = formatdate()
    return msg
def send(from_addr, to_addrs, msg):  # For email
    try:
        print('Preparing for email sending 1')
        #smtpobj = smtplib.SMTP('smtp.gmail.com', 587)
        #smtpobj = smtplib.SMTP('smtp.mail.goo.jp', 465)
        if SecurityTypeVar.get() == "TLS":
            print("Security type: TLS")
            smtpobj = smtplib.SMTP(SmtpServerVar.get(), int(SmtpPortVar.get()))
        if SecurityTypeVar.get() == "SSL":
            print("Security type: SSL")
            smtpobj = smtplib.SMTP_SSL(SmtpServerVar.get(), int(SmtpPortVar.get()))
        print('Preparing for email sending 2')
        #smtpobj.connect(SmtpServerVar.get(), int(SmtpPortVar.get()))
        smtpobj.ehlo()
        #smtpobj.set_debuglevel(True)
        if SecurityTypeVar.get() == "TLS":
            smtpobj.starttls()
            smtpobj.ehlo()
        print('Start login...')
        smtpobj.login(SenderAddressVar.get(), SenderPasswordVar.get())
        print('Succeeded to login the SMTP server')
        #smtpobj.sendmail(from_addr, to_addrs, msg.as_string())
        smtpobj.sendmail(SenderAddressVar.get(), RecipientAddressVar.get(), msg.as_string())
        print('The email sent!')
        smtpobj.close()
    except:
        print('Failed to send email...')
    return
def SendMail(SUBJECT, BODY):  # For email
    #global RecipientAddress
    if RecipientAddressVar.get() !='' and SenderAddressVar.get() !='' and SenderPasswordVar.get() !='':
        #print("ma")
        to_addr = RecipientAddressVar.get()
        subject = SUBJECT
        body = BODY
        msg = create_message(SenderAddressVar.get(), to_addr, BCC, subject, body)
        send(SenderAddressVar.get(), to_addr, msg)
    return


# Summary of menu bar
# File-> SaveParameter
# Setting -> adjustPanelLoc, SetTaskSchedule,RecFPS,PlayFPS,encoder,SetEmail,resetPara, FreezeDetect, Blinder
# Manual -> startRecord, endRecord, ResetMicon, ResetCam
#menubar = Menu(MainWindowRoot)
#FileMenu = Menu(menubar, tearoff=0)
#FileMenu.add_command(label="Save parameters", command=SaveTrgOn)
#FileMenu.add_command(label="Reset parameters", command=donothing)
#FileMenu.add_command(label="Exit", command=EndFlagOn)
#menubar.add_cascade(label="File", menu=FileMenu)
#SettingMenu = Menu(menubar, tearoff=0)
#SettingMenu.add_command(label="Adjust panel position", command=SetPanel)
#SettingMenu.add_command(label="Set task schedule", command=donothing)
#SettingMenu.add_command(label="Set video recording FPS", command=donothing)
#SettingMenu.add_command(label="Set video playback FPS", command=donothing)
#SettingMenu.add_command(label="Select encoder", command=donothing)
#SettingMenu.add_command(label="Set notification email", command=donothing)
#SettingMenu.add_command(label="Freeze detection mode", command=donothing)
#SettingMenu.add_command(label="Blinder mode", command=donothing)
#menubar.add_cascade(label="Setting", menu=SettingMenu)
#ManualMenue = Menu(menubar, tearoff=0)
#ManualMenue.add_command(label="Start record", command=donothing)
#ManualMenue.add_command(label="Stop record", command=donothing)
#ManualMenue.add_command(label="Reset microcomputer", command=donothing)
#ManualMenue.add_command(label="Reset camera", command=donothing)
#menubar.add_cascade(label="Manual operation", menu=ManualMenue)
#MainWindowRoot.config(menu=menubar)

# Make menu GUI
PathForSaving=StringVar(MainWindowRoot)
PathForSaving.set(Path)
mPathForSaving = ttk.Label(MainWindowLeftFrame, textvariable=PathForSaving)
mPathForSaving.place(x=320, y=0)    #350 245
StrFPS = StringVar(MainWindowRoot)
mFPS = ttk.Label(MainWindowLeftFrame, textvariable=StrFPS)
mFPS.place(x=0, y=178)  #165
CurrStatusDispVar = StringVar(MainWindowRoot)
CurrStatusDispVar.set("")
mCurrStatusDisp = ttk.Label(MainWindowLeftFrame, textvariable=CurrStatusDispVar)
mCurrStatusDisp.place(x=0, y=195)   #182
AWS_DispTime="" # Keep text for AWS
#AWS_DispTimeVar = StringVar(MainWindowRoot)
#mAWS_DispTime = ttk.Label(MainWindowLeftFrame, textvariable=AWS_DispTimeVar)
#mAWS_DispTime.place(x=50, y=165) #195


bIsTouchWindowOn = ttk.Button(MainWindowLeftFrame, text='TouchWin', command=ToggleTouchWindow)
bIsTouchWindowOn.place(x=0, y=0)
bIsCameraWinEnlarged = ttk.Button(MainWindowLeftFrame, text='CamSize', command=ToggleCamWin)
bIsCameraWinEnlarged.place(x=100, y=0)
bIsCameraWinEnlarged = ttk.Button(MainWindowLeftFrame, text='PanelBlink', command=ToggleManualBlinkPanel)
bIsCameraWinEnlarged.place(x=200, y=0)

YShift=30
bFolderPath = ttk.Button(MainWindowLeftFrame, text='Folder path', command=SelectPathForSaving)
bFolderPath.place(x=0, y=YShift)
YShift+=25
bSaveTrgOn = ttk.Button(MainWindowLeftFrame, text='SavePara', command=SaveTrgOn)
bSaveTrgOn.place(x=0, y=YShift)
YShift+=25
bSwitch = ttk.Button(MainWindowLeftFrame, text='CopyROI', command=CopyRoi)
bSwitch.place(x=0, y=YShift)
YShift+=25
bSwitch = ttk.Button(MainWindowLeftFrame, text='Setting', command=Setting)
bSwitch.place(x=0, y=YShift)
YShift+=25
bSwitch = ttk.Button(MainWindowLeftFrame, text='Setting2', command=Setting2)
bSwitch.place(x=0, y=YShift)
YShift+=25
bExit = ttk.Button(MainWindowLeftFrame, text='Exit', command=EndFlagOn)
bExit.place(x=0, y=YShift)
PutTaskButton()


# Make symbol
sTouchCursor=CanvasTouchWindow.create_oval(0, 0, 10, 10, fill = 'orange')  # Draw touch cursor


'''
# Make Input
for i in range(ServoChNum): #
    if 
InAngleVar = StringVar(ServoWindowRoot)
iInAngle = ttk.Entry(ServoWindowFrame, textvariable=InAngleVar, width=5)
iInAngle.grid(row=4, column=2, sticky=W)
MidAngleVar = StringVar(ServoWindowRoot)
iMidAngle = ttk.Entry(ServoWindowFrame, textvariable=MidAngleVar, width=5)
iMidAngle.grid(row=5, column=2, sticky=W)
OutAngleVar = StringVar(ServoWindowRoot)
iOutAngle = ttk.Entry(ServoWindowFrame, textvariable=OutAngleVar, width=5)
iOutAngle.grid(row=6, column=2, sticky=W)

# Make Button

bInAngle = ttk.Button(ServoWindowFrame, text='InAngle', command=lambda: ServoPosInside(3))
bInAngle.grid(row=9, column=1, sticky=W)
bMidAngle = ttk.Button(ServoWindowFrame, text='MidAngle', command=lambda: ServoPosMiddle(3))
bMidAngle.grid(row=10, column=1, sticky=W)
bOutAngle = ttk.Button(ServoWindowFrame, text='OutAngle', command=lambda: ServoPosOutside(3))
bOutAngle.grid(row=11, column=1, sticky=W)
'''
ButtonAWS_DurVar = StringVar(ServoWindowRoot)
iButtonAWS_Dur = ttk.Entry(ServoWindowFrame2, textvariable=ButtonAWS_DurVar, width=5)
iButtonAWS_Dur.grid(row=15, column=2, sticky=W)

bAWS = ttk.Button(ServoWindowFrame2, text='AWS(sec)', command=ButtonAWS)   #
bAWS.grid(row=15, column=1, sticky=W)

bAWS = ttk.Button(ServoWindowFrame2, text='AWS(sec,Blink)', command=ButtonAWS_Blink)   #
bAWS.grid(row=16, column=1, sticky=W)

bShowPanel = ttk.Button(ServoWindowFrame2, text='ShowPanel', command=ToggleManualPanel)
bShowPanel.grid(row=20, column=1, sticky=W)
if RaspberryMode==0:
    #VideoCapture = cv2.VideoCapture(CameraID)

    if WinApiForCamera==0:
        VideoCapture = cv2.VideoCapture(CameraID, cv2.CAP_DSHOW)  # Make video capture
        if CamExposureFix == 1:
            VideoCapture.set(cv2.CAP_PROP_AUTO_EXPOSURE, 0)  # Switch to manual-exposure mode of the camera
            #VideoCapture.set(cv2.CAP_PROP_EXPOSURE, -8)  # Change exposure (value: -16 to 0)
            #VideoCapture.set(cv2.CAP_PROP_SATURATION, 64)
            #VideoCapture.set(cv2.CAP_PROP_GAIN, 255)    # fixed at -1
            #VideoCapture.set(cv2.CAP_PROP_BRIGHTNESS, 100) #Max255
            #VideoCapture.set(cv2.CAP_PROP_CONTRAST, 100)  # Max255

    if WinApiForCamera==1:
        VideoCapture = cv2.VideoCapture(CameraID, cv2.CAP_MSMF)       #Make video capture
        #VideoCapture = cv2.VideoCapture(0)
if RaspberryMode==1:
    if CamExposureFix == 0:
        VideoCapture = cv2.VideoCapture(CameraID)
    if CamExposureFix == 1:
        if CamExposureFixMode == 1:
            subprocess.run(['v4l2-ctl', '-d', '/dev/video0', '-c', 'auto_exposure=1'])  # Hashizume
        VideoCapture = cv2.VideoCapture(CameraID, cv2.CAP_V4L2)
        if CamExposureFixMode == 0:
            VideoCapture.set(cv2.CAP_PROP_AUTO_EXPOSURE, 0)  # Switch to manual-exposure mode of the camera
        #VideoCapture.set(cv2.CAP_PROP_EXPOSURE, 100)  # Change exposure (value: -16 to 0)
VideoCapture.set(cv2.CAP_PROP_FPS, TargetFps)    # Set FPS of camera capturing
CameraResolutionX = VideoCapture.get(cv2.CAP_PROP_FRAME_WIDTH)
CameraResolutionY = VideoCapture.get(cv2.CAP_PROP_FRAME_HEIGHT)
print("Camera resolution: x "+str(CameraResolutionX)+" y "+str(CameraResolutionY))
#VideoCapture.set(cv2.CAP_PROP_POS_FRAMES, 0);  # Useless
#VideoCapture.set(cv2.CAP_PROP_BUFFERSIZE, 3);  # Useless

cv2.namedWindow("CameraWindow")                     #Make video window
cv2.moveWindow("CameraWindow", CameraWindowPosX, CameraWindowPosY)
mouseData = mouseParam("CameraWindow") # Instantiate class for get mouse cursor coordinates of camera window


def InitLickWriter():   # Inisiate txt export of lick log function
    global Writer_LickEventTxt, Writer_LickEventCsv, Path
    Writer_LickEventTxt = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(Task) + " Lick.txt", 'w')  # Initialize the text exporter
    Writer_LickEventCsv = open(Path + "/" + str(TimeNow.year) + "_" + str(TimeNow.month) + "_" + str(TimeNow.day) + " " + str(TimeNow.hour) + "h" + str(TimeNow.minute) + "m Task" + str(Task) + " Lick.csv", 'w')  # Initialize the text exporter
    return
def EndLickWriter():   # End txt export of lick log function
    global Writer_LickEventTxt, Writer_LickEventCsv
    Writer_LickEventTxt.close()
    Writer_LickEventCsv.close()
    return

def OperantHouseUpdate():
    global FrameNum, OHCnt, TimeNow, FpsPreSec, FpsSec, NowRecording, RecordFps, PlayBackFps, FrameNumPerSec, w, EndFlag, BreakFlag,frame,VideoWriter,Line, MainWindowRoot, ServoWindowRoot,TouchWindowRoot,ret, Img, frame,cv2,Phase, TimerRunning, TimerNowTime, TimerPreTime, TimerCounter, TimerSec, TouchSymbolCnt, NosePokeRoiULX, NosePokeRoiULY, NosePokeRoiBRX, NosePokeRoiBRY, NosePokeRoiWidth, NosePokeRoiHeight, TouchSymbolCnt, MxCam, MyCam, RoiMovePhase,GrabbedRoiVertex, GrabbedID, Position, Distance, CapturedImgWidth, CapturedImgHeight,CameraWindowScaleX, CameraWindowScaleY, NowPunishing, NosePokeTh, NosePokeDetectionOn, StartLickRecordingTrg, NowLickRecording, EndLickRecordingTrg, EndRecordTimerOn, EndRecordTimerCnt, TtlCurrTime, Ttl1stSquareDuration, ElapsedTimePerFrame, ElapsedTime, TtlCurrQuotient, TtlCurrRemainder, TtlSquareElapsedTime, TtlPreQuotient, TtlCnt, TtlSquareElapsedTime, TtlIsFirst, TtlOutputOn, TtlPreTime, TtlPower, SendingTtl, NextShatterTime, CaptureNum, FPS, Writer_LickEventTxt, CurrentChannelID, IndicatedDigitalOut, DigitalOut, MxDesk, MyDesk, TouchX, TouchY, PreTouchX, PreTouchY,sTouchCursor, ServoWorkTime, Angle, TempAngle, ServoOutputBook, DigitalPinOutputBook, BlinkPanelNum,IsHiddenPanel,TypeOfPanel, IsWaterCueBlink, WaterCuePower, AWS_On, AWS_IndicatedDur, AWS_Dur, AWS_PreFrameMilliSec, AWS_CurrFrameMilliSec, AWS_Stat, TouchDetectionOnCnt, DebugWithoutArduinoMode, PointedPixelInt, IsThereEndTaskNowButton, DuringCameraReset, VideoCapture, mouseData, WinApiForCamera, TargetFps, IsLightPhase, AutoTaskSwitchPhase, NextTaskID, TouchCursorON,  MouseInput, RoiUsed, Roi1X, Roi1Y, Roi2X, Roi2Y, RoiSamplingNum, RoiHitNum, RoiDetect, RoiPreDetect, StepX, StepY, ShowRoi,ManualRoiDetectionCnt,ManualRoiDetectionID, TouchDetectSensorType, IsTouchWindowOn, TouchWindowToggle, LightCycleControl, RoiIntLog, HighestInt, IntArray, PreRoiIntArray, PanelFrameCnt, RoiDensity, PanelChanged, ManualBlinkPanelOnTrg, ManualBlinkPanelOn, ManualBlinkPanelRef, AWS_DispTime, TouchX_Scale, TouchY_Scale, TouchX_Shift, TouchY_Shift,DigitalOutBlinkActive, OutInt, ServoAngle, InputText, AnalogInputBytes, InputFromArduinoEnabled, RoiProperty, BlinkFreq, OutInt, RoiDetectNum, LeverPressNum, DigitalOutGuiUpdateTrg, IndicatedDigitalIn, DigitalIn, RoiInitDark, RoiInitLight   #
    #print(VideoCapture.get(cv2.CAP_PROP_GAIN))  #tagg
    #print(VideoCapture.get(cv2.CAP_PROP_BRIGHTNESS))
    #print(VideoCapture.get(cv2.CAP_PROP_CONTRAST))
    #print(VideoCapture.get(cv2.CAP_PROP_SATURATION))

    OHCnt+=1    # Counter
    #print('Phase: '+str(Phase)+'  Phase2: '+str(Phase2)+'  Task: '+str(Task)+' @'+str(CrossFireMoveDistance))
    # Declaration of local variables
    RoiR=255
    RoiG = 0
    RoiB = 0
    Red=0
    Green=0
    Blue=0
    Int=0
    SamplingPosX = 0
    SamplingPosY = 0
    #Angle=90
    TouchXAdjust = 0
    TouchYAdjust = 0
    TtlPowerOn = 0

    # Caliculate FPS
    FrameNum += 1
    TimeNow = datetime.datetime.now()
    FpsPreSec = FpsSec
    FpsSec = TimeNow.second
    if FpsSec != FpsPreSec:
        FPS=FrameNumPerSec
        StrFPS.set("FPS "+str(FPS))
        FrameNumPerSec=0
    else:
        FrameNumPerSec+=1

    if NowRecording == 1:
        NowRecordingDisp='ON '
    if NowRecording == 0:
        NowRecordingDisp='OFF'
    PointedPixelIntDisp=int(PointedPixelInt)

    TempText=""
    for i in range(10): # Make text of DispVariable(User configured variable display)
        if DispVariable[i][1]=='':
            break
        TempText += " "
        TempText += DispVariable[i][0]
        TempText += ":"
        TempText+=DispVariable[i][1]
    CurrStatusDispVar.set(str(TimeNow.month)+'/'+str(TimeNow.day)+' '+str(TimeNow.hour)+':'+str(TimeNow.minute)+':'+str(TimeNow.second)+'  LightInt:'+str(int(PointedPixelIntDisp))+' Servo:'+str(Angle)+' Rec:'+NowRecordingDisp+' Cam('+str(MxCam)+', '+str(MyCam)+') Touch('+str(TouchX)+', '+str(TouchY)+') Phase:'+str(Phase) + TempText+' '+AWS_DispTime+' Roof LED:'+str(DigitalOut[13])+' IR LED:'+str(DigitalOut[12])+' Cue LED:'+str(DigitalOut[11]))#+' @'+str(ManualBlinkPanelOnTrg))

    if TouchWindowToggle==1:    # If touch toggle button is clicked
        if TouchDetectSensorType==0:    # If camera nosepoke detection mode
            TouchWindowToggle = 0
        IsTouchWindowOn = 1
        TouchWindowRoot.geometry('+' + str(ULXofTouchWindow) + '+' + str(ULYofTouchWindow))  # Move window

    if TouchWindowToggle==-1:
        if TouchDetectSensorType == 0:  # If camera nosepoke detection mode
            TouchWindowToggle = 0
        IsTouchWindowOn = -1
        TouchWindowRoot.geometry('+' + str(ULXofTouchWindow+2000) + '+' + str(ULYofTouchWindow+2000))  # Move window

    if TouchDetectSensorType==0:
        if OHCnt%1800==0:   # Move to the right position regulary
            if IsTouchWindowOn == 1:
                TouchWindowRoot.geometry('+' + str(ULXofTouchWindow) + '+' + str(ULYofTouchWindow))  # Move window
            if IsTouchWindowOn == -1:
                TouchWindowRoot.geometry('+' + str(ULXofTouchWindow + 2000) + '+' + str(ULYofTouchWindow + 2000))  # Move window

    PreTouchX = TouchX
    PreTouchY = TouchY

    if MouseDebugModeVar.get() == 'OFF' and TouchDetectSensorType == 1:
        #MxDesk, MyDesk = win32api.GetCursorPos()    # Get mice coordinates
        try:
            TouchX_Shift=int(TouchX_ShiftVar.get())
        except ValueError:
            print("The value of touchX shift is not int type")
        try:
            TouchY_Shift=int(TouchY_ShiftVar.get())
        except ValueError:
            print("The value of touchY shift is not int type")

        if TouchX_ScaleVar.get().replace(".","").isdigit():
            TouchX_Scale=float(TouchX_ScaleVar.get())
        if TouchY_ScaleVar.get().replace(".","").isdigit():
            TouchY_Scale=float(TouchY_ScaleVar.get())
        if TouchX_Scale!=0 and TouchY_Scale!=0:
            fMxTk = float(MxTk)
            fMyTk = float(MyTk)
            TouchX = int(-(fMyTk * 1.73 * TouchX_Scale - 1350 - TouchX_Shift))  # Airbar is compatible with 15.6 inches, while monitor is 10 inches
            TouchY = int((fMxTk * 0.87 * TouchY_Scale -320 -TouchY_Shift))  #

    if MouseDebugModeVar.get() == 'ON':
        TouchX = MxTk
        TouchY = MyTk
    if TouchX != PreTouchX or TouchY != PreTouchY:
        TouchDetectionOnCnt = 2
        TouchSymbolCnt = 30
    if TouchCursorON == 1:
        CanvasTouchWindow.coords(sTouchCursor, TouchX-5,TouchY-5,TouchX+5,TouchY+5) # Move touch cursor
    if TouchCursorON == 0:
        CanvasTouchWindow.coords(sTouchCursor, 0,0,0,0) # Move touch cursor


    # Update each windows
    MainWindowRoot.update()
    ServoWindowRoot.update()
    TouchWindowRoot.update()
    #DOutWindowRoot.update()


    # Change illumination based on light cycle
    if IsHousingAnalysis==1 and LightCycleControl==1 and AWS_On == 0:
        LightOnsetTime = LightPhaseOnsetHour * 60+LightPhaseOnsetMinute # assign light phase onset time as minute
        DarkOnsetTime = DarkPhaseOnsetHour * 60 + DarkPhaseOnsetMinute # Assign dark phase onset time as minute
        CurrTime= TimeNow.hour*60+TimeNow.minute    # Assign current time as minute
        Trg=0
        if LightOnsetTime < DarkOnsetTime:
            if CurrTime>=LightOnsetTime and CurrTime<=DarkOnsetTime :   # If the order of phases are "DarkPhase -> LightPhase -> DarkPhase"
                if DigitalOut[13]==0:
                    RoofLightOn()
                if DigitalOut[12]==1:
                    InfraredLightOff()
                Trg=1
            if Trg==0:
                if DigitalOut[13] == 1:
                    RoofLightOff()
                if DigitalOut[12]==0:
                    InfraredLightOn()
        Trg = 0
        if LightOnsetTime > DarkOnsetTime:
            if CurrTime>=LightOnsetTime or CurrTime<=DarkOnsetTime :   # If the order of phases are "LightPhase -> DarkPhase -> LightPhase"
                if DigitalOut[13] == 0:
                    RoofLightOn()
                if DigitalOut[12]==1:
                    InfraredLightOff()
                Trg=1
            if Trg==0:
                if DigitalOut[13] == 1:
                    RoofLightOff()
                if DigitalOut[12]==0:
                    InfraredLightOn()
    
    Trg=0
    if AutoTaskSwitchPhase==1:  # If task switch is booked
        BackToPara()
        AutoTaskSwitchPhase = 2
        Trg = 1
    if AutoTaskSwitchPhase==2 and  Trg==0:
        Back()
        AutoTaskSwitchPhase = 3
        Trg = 1
    if AutoTaskSwitchPhase == 3 and  Trg==0:
        if Phase==0:    # When it comes to task selection
            AutoTaskSwitchPhase = 4
            SwitchToSelectedTask(NextTaskID)  # Initialize for the starting of the task
    if AutoTaskSwitchPhase==4 and Trg==0:
        AutoTaskSwitchPhase = 5
        Trg=1
    if AutoTaskSwitchPhase==5 and Trg==0:
        Start()
        AutoTaskSwitchPhase = 6


    Captured =0
    if DuringCameraReset==0:
        if CameraCaptureFreqVar.get()!='':
            if OHCnt%int(CameraCaptureFreqVar.get())==0:
                ret, Img = VideoCapture.read()  # Capture camera image
                #print(np.shape(Img))

                Captured=1
                #print(VideoCapture.get(cv2.CAP_PROP_FPS))
                #print(VideoCapture.grab())
                #if VideoCapture.grab():
                #    ret, Img = VideoCapture.retrieve()
                #print(VideoCapture.get(7))
            else:
                time.sleep(1. / TargetFps)  # Wait for keeping target frame rate
    if StartLickRecordingTrg==1:    # If recording of lick onset and offset is activated
        StartLickRecordingTrg = 0
        if NowLickRecording == 0:
            InitLickWriter()        # Init text export object of lick
            NowLickRecording = 1
    if EndLickRecordingTrg == 1:
        EndLickRecordingTrg = 0
        if NowLickRecording == 1:
            EndLickWriter()
            NowLickRecording = 0
    # Process of the movement of the nosepoke ROI
    #cv2.waitKey(1)
    #MouseInput=mouseData.getEvent()
    #print(MouseInput)
    MxCam = mouseData.getX()   # Get mouse cursor coordinate
    MyCam = mouseData.getY()
    if type(MxCam) == int and MyCam == mouseData.getY():
        MxCam = int(MxCam * CameraWindowScaleX)
        MyCam = int(MyCam * CameraWindowScaleY)
        if MxCam >= CapturedImgWidth:
            MxCam = CapturedImgWidth-1
        if MyCam >= CapturedImgHeight:
            MyCam = CapturedImgHeight-1
    #print(str(MxCam)+","+str(MyCam))
    if ShowRoi == 1:    #
        # Move water slit nosepoke and touch ROI
        if RoiMovePhase == 3:
            if MouseInput == 0 or MouseInput == 4: # If left click is released again
                RoiMovePhase = 0    # Get back the ROI phase
                GrabbedID = -1
                GrabbedRoiVertex = -1
        BreakTrg=0

        if RoiMovePhase == 0:
            for i in range(MaxRoiNum):  # Measure distances between mouse cursor and each tab of nose poke ROI
                if RoiUsed[Task][i]==1:
                    if BreakTrg == 1:
                        break
                    if MouseInput == 1 or MouseInput == 7:
                        Position[0][0]=MxCam
                        Position[0][1]=MyCam
                        for i2 in range(2):
                            if BreakTrg == 1:
                                break
                            if i2==0:
                                Distance = MeasureDistanceSquare(Roi1X[Task][i], Roi1Y[Task][i], MxCam, MyCam) # Measure distance
                            if i2==1:
                                Distance = MeasureDistanceSquare(Roi2X[Task][i], Roi2Y[Task][i], MxCam, MyCam) # Measure distance
                            if Distance < 256:   # If mouse cursor and tab are close enough
                                GrabbedID = i # Keep which roi is selected
                                GrabbedRoiVertex = i2
                                RoiMovePhase = 1
                                BreakTrg = 1

        if RoiMovePhase==1 or RoiMovePhase==2:  # Move ROI tab according to the mouse cursor
            if GrabbedRoiVertex == 0:
                Roi1X[Task][GrabbedID] = MxCam
                Roi1Y[Task][GrabbedID] = MyCam
                if Roi1X[Task][GrabbedID] < 5:  # Limit the positions of the ROI tab not to stick out from the window
                    Roi1X[Task][GrabbedID] = 5
                if Roi1Y[Task][GrabbedID] < 5:
                    Roi1Y[Task][GrabbedID] = 5
                if Roi1X[Task][GrabbedID] > CapturedImgWidth - 10:
                    Roi1X[Task][GrabbedID] = CapturedImgWidth - 10
                if Roi1Y[Task][GrabbedID] > CapturedImgHeight - 10:
                    Roi1Y[Task][GrabbedID] = CapturedImgHeight - 10
                with open('data/Roi1X.dat', 'wb') as fp:   # Save position of the tabs every frame
                    pickle.dump(Roi1X, fp)  # Save
                with open('data/Roi1Y.dat', 'wb') as fp:
                    pickle.dump(Roi1Y, fp)  # Save

            if GrabbedRoiVertex == 1:
                Roi2X[Task][GrabbedID] = MxCam
                Roi2Y[Task][GrabbedID] = MyCam
                if Roi2X[Task][GrabbedID] < 5:  # Limit the positions of the ROI tab not to stick out from the window
                    Roi2X[Task][GrabbedID] = 5
                if Roi2Y[Task][GrabbedID] < 5:
                    Roi2Y[Task][GrabbedID] = 5
                if Roi2X[Task][GrabbedID] > CapturedImgWidth - 10:
                    Roi2X[Task][GrabbedID] = CapturedImgWidth - 10
                if Roi2Y[Task][GrabbedID] > CapturedImgHeight - 10:
                    Roi2Y[Task][GrabbedID] = CapturedImgHeight - 10
                with open('data/Roi2X.dat', 'wb') as fp:   # Save position of the tabs every frame
                    pickle.dump(Roi2X, fp)  # Save
                with open('data/Roi2Y.dat', 'wb') as fp:
                    pickle.dump(Roi2Y, fp)  # Save

            if MouseInput == 0 or MouseInput == 4:   # If left click is released
                RoiMovePhase = 2
        if RoiMovePhase == 2:
            if MouseInput == 1 or MouseInput == 7: # If left click again
                RoiMovePhase = 3

        if RoiMovePhase == 0:   # If ROI is not moving
            RoiB = 255  # Change ROI color to blue
            RoiG = 0
            RoiR = 0
        if RoiMovePhase >= 1:   # If ROI is moving
            RoiB = 255  # Change ROI color to light blue
            RoiG = 100
            RoiR = 100

        if TouchSymbolCnt > 0:  # Process of touch symbol
            TouchSymbolCnt-=1
            cv2.rectangle(Img, (5,5), (80,45), (255, 255, 255), -1)  # Draw panel touching symbol

        if DigitalOut[0] == 1:
            cv2.rectangle(Img, (80, 5), (155, 45), (255, 0, 0), -1)  # Draw digitalout symbol (Blue)??
        if DigitalOut[1] == 1:
            cv2.rectangle(Img, (155, 5), (230, 45), (0, 255, 255), -1)  # Draw digitalout symbol (Yellow)
        if DigitalOut[2] == 1:
            cv2.rectangle(Img, (230, 5), (305, 45), (255, 255, 0), -1)  # Draw digitalout symbol (Green)
        if DigitalOut[3] == 1:
            cv2.rectangle(Img, (305, 5), (380, 45), (0, 127, 255), -1)  # Draw digitalout symbol (Orange)

        if NosePokeDetectionOn==0:
            if TimerSec[6] > float(TouchOffTimeVar.get()):
                Timer_End(6)
                NosePokeDetectionOn=1
        # Measuring the light intensity of the pointed pixel
        if MxCam!=None:
            Blue = Img[MyCam, MxCam, 0]
            Green = Img[MyCam, MxCam, 1]
            Red = Img[MyCam, MxCam, 2]
        PointedPixelInt=(int(Blue)+int(Green)+int(Red))/3

        if TouchDetectSensorType==1:# If airbar mode is activated
            for i in range(MaxRoiNum):  # Inactivate ROIs which are overlaped with panels associated with air bar detection
                if PanelUsed[Task][i]==1:
                    RoiUsed[Task][i] = 0    # The ROIs are inactivated

        for i in range(MaxRoiNum):  # update positions of sampling points
            if RoiUsed[Task][i] == 1:
                RoiLengthX = Roi2X[Task][i] - Roi1X[Task][i]
                RoiLengthY = Roi2Y[Task][i] - Roi1Y[Task][i]
                RoiLength = MeasureDistance(Roi1X[Task][i], Roi1Y[Task][i], Roi2X[Task][i], Roi2Y[Task][i])
                RoiSamplingNum[i] = int(RoiLength / 100.0 * RoiDensity + 1)  # Caliculate sampling points number of each ROI
                if RoiLengthX != 0:
                    RoiAngle = math.atan(float(RoiLengthY) / float(RoiLengthX))  # Caliculate anlge of line
                if RoiLengthX == 0:
                    if Roi2Y[Task][i] > Roi1Y[Task][i]:  # If the angle is +90 degree
                        RoiAngle = math.pi / 2.0
                    if Roi2Y[Task][i] < Roi1Y[Task][i]:  # If the angle is -90 degree
                        RoiAngle = -math.pi / 2.0
                if RoiSamplingNum[i] > 1:
                    if Roi1X[Task][i] <= Roi2X[Task][i]:
                        StepX[i] = math.cos(RoiAngle) * RoiLength / float(RoiSamplingNum[i] - 1)  # Caliculate x/y step between sampling dots
                        StepY[i] = math.sin(RoiAngle) * RoiLength / float(RoiSamplingNum[i] - 1)
                    if Roi1X[Task][i] > Roi2X[Task][i]:
                        StepX[i] = -math.cos(RoiAngle) * RoiLength / float(RoiSamplingNum[i] - 1)
                        StepY[i] = -math.sin(RoiAngle) * RoiLength / float(RoiSamplingNum[i] - 1)

        if RoiDensity > 0 and Captured == 1 and PanelChanged == 0:
            for i in range(MaxRoiNum):  # Per each ROI
                if NowPunishing == 1 or NosePokeDetectionOn == 0:
                    continue    # If water detection is off, skip ROI #0 detection
                if RoiUsed[Task][i] == 1:
                    RoiPreDetect[Task][i] = RoiDetect[Task][i]
                    if DigitalOut[13] == 1:
                        if LightThListVar[Task][i].get().isdigit():  # Check whether the string is digit
                            NosePokeTh = int(LightThListVar[Task][i].get())  # Set the threshold of light phase
                    if DigitalOut[13] == 0:
                        if DarkThListVar[Task][i].get().isdigit():  # Check whether the string is digit
                            NosePokeTh = int(DarkThListVar[Task][i].get())  # Set the threshold of dark phase
                    RoiHitNum[Task][i] = 0

                    if RoiProperty[i][0] == 0 or RoiProperty[i][0] == 2:  # If Nosepoke detection mode is simple thresholding mode
                        NosePokeIntTh = NosePokeTh
                        for i2 in range(RoiSamplingNum[i]):  # Per each sampling point
                            SamplingPosX = Roi1X[Task][i] + int(StepX[i] * i2)
                            SamplingPosY = Roi1Y[Task][i] + int(StepY[i] * i2)

                            if RoiProperty[i][0] == 0:
                                # if CableDetectCorrValueVar.get() == "0":  # If this ROI isn't water ROI or cable ignore mode is off
                                Red = Img[SamplingPosY, SamplingPosX, 2]  # Get color intensity of the pixel
                                Trg = 0
                                if RoiProperty[i][1] == 0:
                                    if Red <= NosePokeIntTh:  # If nosepoke is detected
                                        Trg = 1
                                if RoiProperty[i][1] == 1:
                                    if Red >= NosePokeIntTh:  # If nosepoke is detected
                                        Trg = 1
                                if Trg == 1:
                                    RoiHitNum[Task][i] += 1
                                    cv2.rectangle(Img, (SamplingPosX - SamplingDotSize, SamplingPosY - SamplingDotSize), (SamplingPosX + SamplingDotSize, SamplingPosY + SamplingDotSize), (0, 0, 255),-1)  # Draw sampling dot
                                if Trg == 0:  # If nosepoke is not detected
                                    #print(str(SamplingPosX)+" "+str(SamplingPosY))
                                    Img[SamplingPosY, SamplingPosX, 0] = 255  # Plot blue dot
                                    Img[SamplingPosY, SamplingPosX, 1] = 255
                                    Img[SamplingPosY, SamplingPosX, 2] = 255  # cv2.rectangle(Img, (SamplingPosX - SamplingDotSize, SamplingPosY - SamplingDotSize), (SamplingPosX + SamplingDotSize, SamplingPosY + SamplingDotSize), (255, 0, 0),-1)  # Draw sampling dot

                            if RoiProperty[i][0] == 2:  # If Nosepoke detection mode is simple thresholding and yellow ingore mode
                                # if CableDetectCorrValueVar.get() != "0":  # If this ROI is water ROI with cable ignore mode
                                Blue = Img[SamplingPosY, SamplingPosX, 0]  # Get color intensities of each pixel
                                Green = Img[SamplingPosY, SamplingPosX, 1]
                                Red = Img[SamplingPosY, SamplingPosX, 2]
                                Int = (int(Blue) + int(Green) + int(Red)) / 3

                                CableIsDetected = 0  # 1 is assignd if cable color is detected
                                if CableDetectCorrValueVar.get().isdigit() and CableDetectCorrValueVar.get() != ".":
                                    if Blue < Green * float(CableDetectCorrValueVar.get()) and Blue < Red * float(
                                            CableDetectCorrValueVar.get()):  # If detected color is yellow(Color of cable of miniscope)
                                        CableIsDetected = 1
                                Trg = 0
                                if RoiProperty[i][1] == 0:
                                    if Int < NosePokeIntTh:  # If light intensity of sampled pixel exceed the threshold
                                        Trg = 1
                                if RoiProperty[i][1] == 1:
                                    if Int > NosePokeIntTh:  # If light intensity of sampled pixel is less than the threshold
                                        Trg = 1

                                if Trg == 1:  # If nosepoke is detected
                                    if CableIsDetected == 1:
                                        cv2.rectangle(Img, (SamplingPosX - 1, SamplingPosY - 1), (SamplingPosX + 1, SamplingPosY + 1), (0, 255, 0), -1)  # Draw blue dot
                                    if CableIsDetected == 0:
                                        RoiHitNum[Task][i] += 1  # Increase the positive sampled pixel number
                                        cv2.rectangle(Img, (SamplingPosX - 1, SamplingPosY - 1), (SamplingPosX + 1, SamplingPosY + 1), (0, 0, 255), -1)  # Draw red dot
                                if Trg == 0:
                                    cv2.rectangle(Img, (SamplingPosX - 1, SamplingPosY - 1), (SamplingPosX + 1, SamplingPosY + 1), (255, 0, 0), -1)  # Draw blue dot

                    if RoiProperty[i][0] == 1:  # If Nosepoke detection mode is "using background history mode"
                        # Count panel exist time
                        if IsHiddenPanel[i - 1] == 0:
                            PanelFrameCnt[i - 1] += 1  # Count existing frame num of each panel
                        if PanelFrameCnt[i - 1] > 1:
                            for i2 in range(RoiSamplingNum[i]):  # Per each sampling point

                                SamplingPosX = Roi1X[Task][i] + int(StepX[i] * i2)  # Caliculate current sampling location
                                SamplingPosY = Roi1Y[Task][i] + int(StepY[i] * i2)
                                SampledInt = Img[SamplingPosY, SamplingPosX, 2]


                                if RoiInitDark[i] == 0:  # If this is the first frame
                                    if DigitalOut[13] == 0:
                                        for i3 in range(5):
                                            RoiIntLogDark[i][i2][i3] = SampledInt  # Keep color intensity into the history log
                                if RoiInitLight[i] == 0:  # If this is the first frame
                                    if DigitalOut[13] == 1:
                                        for i3 in range(5):
                                            RoiIntLogLight[i][i2][i3] = SampledInt  # Keep color intensity into the history log

                                NosePokeIntTh = float(NosePokeTh)
                                Trg = 0
                                if DigitalOut[13] == 0:
                                    if RoiProperty[i][1] == 1:  # If detecting light color object
                                        for i3 in range(5):  # Compare pixel int with history
                                            if RoiIntLogDark[i][i2][i3] <= SampledInt - NosePokeIntTh:  # If nosepoke is detected
                                                Trg = 1
                                                break
                                    if RoiProperty[i][1] == 0:  # If detecting dark color object
                                        for i3 in range(5):  # Compare pixel int with history
                                            if RoiIntLogDark[i][i2][i3] >= SampledInt + NosePokeIntTh:  # If nosepoke is detected
                                                Trg = 1
                                                break
                                if DigitalOut[13] == 1:
                                    if RoiProperty[i][1] == 1:  # If detecting light color object
                                        for i3 in range(5):  # Compare pixel int with history
                                            if RoiIntLogLight[i][i2][i3] <= SampledInt - NosePokeIntTh:  # If nosepoke is detected
                                                Trg = 1
                                                break
                                    if RoiProperty[i][1] == 0:  # If detecting dark color object
                                        for i3 in range(5):  # Compare pixel int with history
                                            if RoiIntLogLight[i][i2][i3] >= SampledInt + NosePokeIntTh:  # If nosepoke is detected
                                                Trg = 1
                                                break
                                if Trg == 1:
                                    RoiHitNum[Task][i] += 1
                                    cv2.rectangle(Img, (SamplingPosX - SamplingDotSize, SamplingPosY - SamplingDotSize), (SamplingPosX + SamplingDotSize, SamplingPosY + SamplingDotSize), (0, 0, 255),
                                        -1)  # Draw sampling dot

                                if OHCnt % 25 == 0:  # Save pixel intensity in every 25 frames tagg
                                    if DigitalOut[13] == 0:
                                        for i3 in range(4):
                                            RoiIntLogDark[i][i2][i3 + 1] = RoiIntLogDark[i][i2][i3]  # Push data
                                        RoiIntLogDark[i][i2][0] = SampledInt  # Keep color intensity into the history log
                                    if DigitalOut[13] == 1:
                                        for i3 in range(4):
                                            RoiIntLogLight[i][i2][i3 + 1] = RoiIntLogLight[i][i2][i3]  # Push data
                                        RoiIntLogLight[i][i2][0] = SampledInt  # Keep color intensity into the history log

                                if Trg == 0:
                                    Img[SamplingPosY, SamplingPosX, 0] = 255  # Plot blue dot
                                    Img[SamplingPosY, SamplingPosX, 1] = 255
                                    Img[SamplingPosY, SamplingPosX, 2] = 255

                                if i2 == 0 or i2 == RoiSamplingNum[i] - 1:
                                    cv2.line(Img, (SamplingPosX - 10, SamplingPosY), (SamplingPosX + 10, SamplingPosY), (255, 255, 255), 1)  # Draw cross hair
                                    cv2.line(Img, (SamplingPosX, SamplingPosY - 10), (SamplingPosX, SamplingPosY + 10), (255, 255, 255), 1)

                            if RoiInitDark[i] == 0:
                                if DigitalOut[13] == 0:
                                    RoiInitDark[i] = 1
                                    #print("di")
                            if RoiInitLight[i] == 0:
                                if DigitalOut[13] == 1:
                                    RoiInitLight[i] = 1
                                    #print("li")

                    TempText = str(i)
                    if NumThListVar[Task][i].get() != "":
                        if RoiHitNum[Task][i] >= int(NumThListVar[Task][i].get()):  # If hit num exceed the threshold for the detection of the nosepoking
                            RoiDetect[Task][i] = 1
                            RabelBlue = 0
                            RabelGreen = 0
                            RabelRed = 255
                            FontLine = 1
                            FontSize = 0.5
                            if i == 0:  # If this ROI is water ROI
                                # RoiDetect[0] = 1
                                if NowLickRecording == 1:
                                    if RoiPreDetect[Task][0] == 0 and RoiDetect[Task][0] == 1:  # if this frame is the onset of nose poke
                                        Writer_LickEventTxt.write(
                                            "NosePokeStart\t1\t" + str(TimeNow.year) + " / " + str(TimeNow.month) + " / " + str(TimeNow.day) + "\t" + str(TimeNow.hour) + ":" + str(
                                                TimeNow.minute) + "\t" + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the onset of the nose poke on the text file
                                        Writer_LickEventCsv.write("NosePokeStart,1," + str(TimeNow.year) + "," + str(TimeNow.month) + "," + str(TimeNow.day) + "," + str(TimeNow.hour) + "," + str(
                                            TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # Write the onset of the nose poke on the csv file

                        if RoiHitNum[Task][i] < int(NumThListVar[Task][i].get()):  # If hit num doesn't exceed the threshold

                            # if i!=0: # If this ROI isn't for water slit or manual nosepoke switch is tuned off
                            RoiDetect[Task][i] = 0
                            RabelBlue = 255
                            RabelGreen = 0
                            RabelRed = 0
                            FontLine = 1
                            FontSize = 0.5

                            if i == ManualRoiDetectionID:  # If manual ROI detection is ON
                                if ManualRoiDetectionCnt > 0:
                                    RoiDetect[Task][ManualRoiDetectionID] = 1
                                    ManualRoiDetectionCnt -= 1
                                    RabelBlue = 0
                                    RabelGreen = 0
                                    RabelRed = 255
                                    FontLine = 1
                                    FontSize = 0.5

                        cv2.putText(Img, TempText, (Roi1X[Task][i] + 2, Roi1Y[Task][i]), cv2.FONT_HERSHEY_SIMPLEX, FontSize, (RabelBlue, RabelGreen, RabelRed),
                            FontLine)  # Window, text, pos, style, scale, color, line

                    if RoiDetect[Task][i] == 1 and RoiProperty[i][2]==1:
                        cv2.rectangle(Img, (Roi2X[Task][i], Roi2Y[Task][i] + 20), (Roi2X[Task][i] + 40, Roi2Y[Task][i] + 60), (0, 0, 255), -1)  # Draw water slit nosepoke symbol

        if Captured == 1:
            PanelChanged = 0

    if CameraWindowScaleX == 1 and CameraWindowScaleY == 1:
        cv2.imshow("CameraWindow", Img)  # Show captured video frame
    if CameraWindowScaleX != 1 or CameraWindowScaleY != 1:
        Img2 = cv2.resize(Img, (int(CapturedImgWidth/CameraWindowScaleX), int(CapturedImgHeight/CameraWindowScaleY)))
        cv2.imshow("CameraWindow", Img2)  # Show captured video frame

    if NowRecording==1: #
        if NextShatterTime <= ElapsedTime:
            if ret == True:
                SmallImg=cv2.resize(Img,(MovieWidth, MovieHeight))
                VideoWriter.write(SmallImg)  # Record captured video of the current frame
                ShatterWaitTime = 1000.0 / float(RecordFps)
                NextShatterTime += ShatterWaitTime
                CaptureNum += 1

            else:
                EndFlag = 1

    cv2.waitKey(1)  # Check mouse input (This command should be this position of this function somehow to detect clicking:other cv2 command should be just after this?)
    MouseInput = mouseData.getEvent()  # Assign mouse input ID

    # Process of Timers
    for i in range(8):  # There are 8 timers (Timer0-3,7 can be used in tasks, Timer4-6 is used for OperantHouseUpdate())
        if TimerRunning[i]==1:
            TimerNowTime[i]=TimeNow.microsecond//100000
            if TimerNowTime[i] != TimerPreTime[i]:  # If it past 0.1 sec
                TimerCounter[i]+=1
                TimerSec[i]=TimerCounter[i]/10.0  # Caliculate time in sec
                TimerPreTime[i]=TimerNowTime[i]
    # Process of blinking panel
    if BlinkPanelNum > 0:
        if int(TimeNow.microsecond) // 100000 % 2 == 0: # When lit-off
            for i in range(0, MaxPanelNum):
                if TypeOfPanel[i] == 1:  # If this panel is assigned to blink
                    CanvasTouchWindow.itemconfigure(TouchPanelRef[i], state='hidden')  # Hide created panel
                    PanelChanged = 0
        if int(TimeNow.microsecond) // 100000 % 2 == 1: # When lit-on
            for i in range(0, MaxPanelNum):
                if TypeOfPanel[i] == 1:   # If this panel is assigned to blink
                    if IsHiddenPanel[i]==0:     # Hidden panel isn't turned on
                        CanvasTouchWindow.itemconfigure(TouchPanelRef[i], state='normal')  # Show created panel
                        PanelChanged = 0

    if ManualBlinkPanelOnTrg==1:    # If manual blink panels are created
        if OHCnt%5==0:
            Trg=0
            if ManualBlinkPanelOn==1:
                ManualBlinkPanelOn = 0
                for i in range(0, MaxPanelNum):
                    CanvasTouchWindow.itemconfigure(ManualBlinkPanelRef[i], state='hidden')  # Hide created panel
                Trg=1
            if ManualBlinkPanelOn == 0 and Trg==0:
                ManualBlinkPanelOn = 1
                for i in range(0, MaxPanelNum):
                    CanvasTouchWindow.itemconfigure(ManualBlinkPanelRef[i], state='normal')  # Hide created panel

    # Process of arbitary water supply (AWS)
    if AWS_On==1:   #
        AWS_PreFrameMilliSec=AWS_CurrFrameMilliSec
        AWS_CurrFrameMilliSec = (TimeNow.hour * 60 * 60 * 1000) + (TimeNow.minute * 60 * 1000) + (TimeNow.second * 1000) + (TimeNow.microsecond//1000)   # Get current time in millisec
        AWS_DispTime='Water supply: '+str(AWS_Dur/1000)+' / '+str(round(AWS_IndicatedDur/1000, 2))+' sec'
        #AWS_DispTimeVar.set('Arbitary water supply: '+str(AWS_Dur/1000)+' / '+str(round(AWS_IndicatedDur/1000, 2))+' sec')
        if DetectRoiNosepoke() == 19:
            AWS_Dur += AWS_CurrFrameMilliSec - AWS_PreFrameMilliSec # Caliculate how long does this frame take
        if AWS_IndicatedDur <= AWS_Dur: # When lick duration exceed the indicated duration
            ServoPosMiddle(3)
            DigitalOutOff(10)
            AWS_Stat=1  # Mean AWS is finished
            AWS_DispTime = ''
            #AWS_DispTimeVar.set('')
            AWS_On=0
    if EndRecordTimerOn==1: # If record end trigger is on
        EndRecordTimerCnt-=1    # Decrease the counter
        if EndRecordTimerCnt<=0:    # If it's time for stop recording
            EndRecording()  # Stop recording
            EndRecordTimerOn=0  # Change recording status variable

    if SendingTtl==1:   # If TTL sending is on
        TtlCurrTime = TimeNow.day*24*60*60*1000 + TimeNow.hour*60*60*1000 + TimeNow.minute*60*1000 + TimeNow.second*1000 + (TimeNow.microsecond//1000)
        ElapsedTimePerFrame = TtlCurrTime - TtlPreTime

        ElapsedTime += ElapsedTimePerFrame
        TtlCurrQuotient = ElapsedTime // TtlITV     # Quotient
        TtlCurrRemainder = ElapsedTime % TtlITV     # Remainder
        Trg = 0
        if TtlPreQuotient < TtlCurrQuotient:
            TtlSquareElapsedTime = TtlCurrRemainder #
            #TtlPower=1 # Turn on TTL output
            DigitalOutOn(11)
            Writer_TtlLogCsv.write(str(TtlCnt) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")  # # Write the timing of TTL onset and offset
            TtlPreQuotient = TtlCurrQuotient
            Trg=1
            TtlCnt+=1
        if DigitalOut[11]==1 and Trg==0:   #
            TtlSquareElapsedTime += ElapsedTimePerFrame #
            if (TtlIsFirst == 1 and TtlSquareElapsedTime >= Ttl1stSquareDuration) or (TtlIsFirst == 0 and TtlSquareElapsedTime >= TtlSquareDuration):   #
                TtlIsFirst= 0
                #TtlPower=-1 # Turn off TTL output
                DigitalOutOff(11)
                Writer_TtlLogCsv.write(str(TtlCnt) + "," + str(TimeNow.hour) + "," + str(TimeNow.minute) + "," + str(TimeNow.second) + "." + str(TimeNow.microsecond // 1000) + "\n")
        TtlPreTime = TtlCurrTime

    for i in range(14): #tagg
        if IndicatedDigitalOut[i]==1:   # If LED light is indicated to be turn on
            IndicatedDigitalOut[i]=0
            DigitalOut[i]=1  # Change hole cue status variable
            DigitalPinOutputBook = 1
            if i==13 and CamExposureFix == 1:
                if RaspberryMode == 0:
                    CamExposureLight = int(CamExposureLightVar.get())
                if RaspberryMode == 1:
                    CamExposureLight = int(float(CamExposureLightVar.get()) * 10.0)
                if CamExposureFixMode == 0:
                    VideoCapture.set(cv2.CAP_PROP_EXPOSURE, CamExposureLight)
                if CamExposureFixMode == 1:
                    subprocess.run(['v4l2-ctl', '-d', '/dev/video0', '-c', f'exposure_time_absolute={CamExposureLight}'])  # Hashizume
                #print(CamExposureLight)
        if IndicatedDigitalOut[i]==-1:  # If LED light is indicated to be turn off
            IndicatedDigitalOut[i] = 0
            DigitalOutBlinkActive[i] = 0
            DigitalOut[i] = 0
            DigitalPinOutputBook = 1
            if i==13 and CamExposureFix == 1:
                if RaspberryMode == 0:
                    CamExposureDark = int(CamExposureDarkVar.get())
                if RaspberryMode == 1:
                    CamExposureDark = int(float(CamExposureDarkVar.get())*10.0)
                if CamExposureFixMode == 0:
                    VideoCapture.set(cv2.CAP_PROP_EXPOSURE, CamExposureDark)
                if CamExposureFixMode == 1:
                    subprocess.run(['v4l2-ctl', '-d', '/dev/video0', '-c', f'exposure_time_absolute={CamExposureDark}'])  # Hashizume
                #print(CamExposureDark)

        if IndicatedDigitalOut[i]==2:   # If LED light is indicated to blink
            DigitalOutBlinkActive[i]=1

        if DigitalOutBlinkActive[i]==1:
            if int(TimeNow.microsecond) // BlinkFreq % 2 == 0: # Make water cue blink (100000)
                DigitalOut[i] = 0
                DigitalPinOutputBook = 1
            if int(TimeNow.microsecond) // BlinkFreq % 2 == 1: # Make water cue blink
                DigitalOut[i] = 1
                DigitalPinOutputBook = 1
        if IndicatedDigitalIn[i]==1:
            IndicatedDigitalIn[i] = 0
            DigitalIn[i] = 1
        if IndicatedDigitalIn[i]==-1:
            IndicatedDigitalIn[i] = 0
            DigitalIn[i] = 0

    if Phase==1 and IsThereEndTaskNowButton==1: #
        RemoveEndTaskNowButton()
        PutPreTaskButton()

    if DigitalPinOutputBook==1 or ServoOutputBook==1:
        DigitalPinOutputBook = 0
        ServoOutputBook = 0
        DigitalOutGuiUpdateTrg = 1
        # 14 letters string contain state of each 14 output channels of Arduino UNO (Ch0,1,2,3,4,5,6,7,8,9,10,11,12,13).
        # ~(126) must be added at the terminal of command as a terminal signal.
        # If the value is 254 or 255, the channel is switched to LED mode. 124 turn on the LED. 125 turn off.
        # If the value is 0-123, the channel is switched to servo mode. 1-124 change PWM value. 125 turn off servo.
        # 124*| 125:} 126:~ 127-:N/A

        #ReadText = ser.readline().decode("utf-8").strip('\n').strip('\r')
        #if OHCnt<1000:
        #ReadText = ser.readline()   #This command read all data accumulated in buffer
        #print(ReadText)
        for i in range(14): # Digital input/output
            if DigitalOut[i]==1:
                OutInt[i]=124   # ON
                #print(OutInt[i])
            if DigitalOut[i]==0:
                OutInt[i]=125   # OFF
                #print(OutInt[i])
            if DigitalIn[i]==1:
                OutInt[i]=123   # ON
            #if DigitalIn[i]==0:
            #    OutInt[i]=122   # OFF
        for i in range(14): # Servo output
            if ServoAngle[i]!=-1:
                if ServoAngle[i] >= 0 and ServoAngle[i] < 122:
                    OutInt[i] = ServoAngle[i]+1
        OutInt[14] = InputFromArduinoEnabled    # Send order to Arduino not to transfer data through serial connection

        #                ch0                               ch1                               ch2                               ch3                                ch4                               ch5                               ch6                               ch7                               ch8                               ch9                                ch10                               ch11                               ch12                              ch13                              Arduino option                     terminate code
        SerialOutBytes = bytes(chr(OutInt[0]), 'utf-8') + bytes(chr(OutInt[1]), 'utf-8') + bytes(chr(OutInt[2]), 'utf-8') + bytes(chr(OutInt[3]), 'utf-8') + bytes(chr(OutInt[4]), 'utf-8') + bytes(chr(OutInt[5]), 'utf-8') + bytes(chr(OutInt[6]), 'utf-8') + bytes(chr(OutInt[7]), 'utf-8') + bytes(chr(OutInt[8]), 'utf-8') + bytes(chr(OutInt[9]), 'utf-8') + bytes(chr(OutInt[10]), 'utf-8') + bytes(chr(OutInt[11]), 'utf-8') + bytes(chr(OutInt[12]),'utf-8') + bytes(chr(OutInt[13]),'utf-8') + bytes(chr(OutInt[14]),'utf-8') + bytes(chr(126),'utf-8')
        #DecimalNum = 128*DigitalOut[3] + 64*DigitalOut[2] + 32*DigitalOut[1] + 16*DigitalOut[0] + 8*RoofLightPowerOn + 4*InfraredPowerOn + 2*WaterCuePower + TtlSquareOn #+8*TtlSquareOn+4*ValveTtlPowerOn+2*DigitalOut[0]+1*HoleWaterCueOn[0]    #Compress LED info into decimal number
        #TempBinary = bytes(chr(DecimalNum), 'utf-8')  # Transform the LED decimal into character and then transform into binary data
        if DebugWithoutArduinoMode==0:
            ser.write(SerialOutBytes)  # Send information into arduino

    if DigitalOutGuiUpdateTrg==1:
        DigitalOutGuiUpdateTrg=0
        UpdateDigitalOutGui()

    if DebugWithoutArduinoMode == 0:
        if InputFromArduinoEnabled==1:
            AnalogInputBytes=ser.readline()
            Trg = 0
            try:
                InputText = str(AnalogInputBytes.decode("utf-8"))  # The data in buffer must be cleared by reading of flushing or arduino will wait and stop
            except:
                InputText=""
                print("UnicodeError")
                Trg=1
            if Trg==0:
                InputText = str(InputText.strip('\n').strip('\r'))
                #print(InputText)
                #print(type(InputText))
        #InputText =ser.readline().decode("utf-8").strip('\n').strip('\r') # The data in buffer must be cleared by reading of flushing or arduino will wait and stop
        #InputText = ser.readline().strip().decode("utf-8") # The data in buffer must be cleared by reading of flushing or arduino will wait and stop
        #print(DetectLeverPress())

        #ser.flushInput()

    if EndFlag > 0:
        EndFlag+=1

    if TouchDetectionOnCnt > 0:
        TouchDetectionOnCnt -= 1
    return



MainWindowRoot.update()
ServoWindowRoot.update()
TouchWindowRoot.update()

# Load the saved general settings
Str = "data"
if os.path.exists(Str) == False:  # If folder for saving general parameters is not exist
    os.mkdir(Str)  # Make folder for saving

if os.path.exists('data/Path.dat') == True: # If the save file is existed
   with open('data/Path.dat', 'rb') as fp:
       Path = pickle.load(fp)
else:
    Path = ''   # Default path for saving
PathForSaving.set(Path)

# Load parameters of control window
if os.path.exists('data/InAngle.dat') == True:  # If the save file is existed
    with open('data/InAngle.dat', 'rb') as fp:
        InAngle=pickle.load(fp)  # Load
else:
    InAngle=[44]*ServoChNum  # Default path for saving  0
for i in range(ServoChNum):  #
    InAngleVar[i].set(str(InAngle[i]))

if os.path.exists('data/MidAngle.dat') == True:  # If the save file is existed
    with open('data/MidAngle.dat', 'rb') as fp:
        MidAngle = pickle.load(fp)  # Load
else:
    MidAngle = [22]*ServoChNum  # Default path for saving  90
for i in range(ServoChNum):  #
    MidAngleVar[i].set(str(MidAngle[i]))

if os.path.exists('data/OutAngle.dat') == True:  # If the save file is existed
    with open('data/OutAngle.dat', 'rb') as fp:
        OutAngle = pickle.load(fp)  # Load
else:
    OutAngle = [0]*ServoChNum  # Default path for saving  0
for i in range(ServoChNum):  #
    OutAngleVar[i].set(str(OutAngle[i]))

if os.path.exists('data/TouchX_Shift.dat') == True:  # If the save file is existed
    with open('data/TouchX_Shift.dat', 'rb') as fp:
        TouchX_ShiftVar.set(pickle.load(fp))  # Load
else:
    TouchX_ShiftVar.set('0')  # Default path for saving

if os.path.exists('data/TouchY_Shift.dat') == True:  # If the save file is existed
    with open('data/TouchY_Shift.dat', 'rb') as fp:
        TouchY_ShiftVar.set(pickle.load(fp))  # Load
else:
    TouchY_ShiftVar.set('0')  # Default path for saving

if os.path.exists('data/TouchX_Scale.dat') == True:  # If the save file is existed
    with open('data/TouchX_Scale.dat', 'rb') as fp:
        TouchX_ScaleVar.set(pickle.load(fp))  # Load
else:
    TouchX_ScaleVar.set('1')  # Default path for saving

if os.path.exists('data/TouchY_Scale.dat') == True:  # If the save file is existed
    with open('data/TouchY_Scale.dat', 'rb') as fp:
        TouchY_ScaleVar.set(pickle.load(fp))  # Load
else:
    TouchY_ScaleVar.set('1')  # Default path for saving

if os.path.exists('data/ButtonAWS_DurVar.dat') == True:  # If the save file is existed
    with open('data/ButtonAWS_DurVar.dat', 'rb') as fp:
        ButtonAWS_DurVar.set(pickle.load(fp))  # Load
else:
    ButtonAWS_DurVar.set("0")  # Default path for saving

if os.path.exists('data/PanelUsed.dat') == True: # Whether each panel is used or not
   with open('data/PanelUsed.dat', 'rb') as fp:
       PanelUsed = pickle.load(fp)
else:
    PanelUsed =  [[0 for i in range(MaxPanelNum)] for j in range(MaxTaskNum)]

if os.path.exists('data/PanelULX.dat') == True: # If the save file is existed
   with open('data/PanelULX.dat', 'rb') as fp:
       PanelULX = pickle.load(fp)
else:
    PanelULX =  [[0 for i in range(MaxPanelNum)] for j in range(MaxTaskNum)]
if os.path.exists('data/PanelULY.dat') == True: # If the save file is existed
    with open('data/PanelULY.dat', 'rb') as fp:
        PanelULY = pickle.load(fp)
else:
    PanelULY =  [[0 for i in range(MaxPanelNum)] for j in range(MaxTaskNum)]

if os.path.exists('data/PanelBRX.dat') == True: # If the save file is existed
    with open('data/PanelBRX.dat', 'rb') as fp:
        PanelBRX = pickle.load(fp)
else:
    PanelBRX = [[0 for i in range(MaxPanelNum)] for j in range(MaxTaskNum)]
if os.path.exists('data/PanelBRY.dat') == True: # If the save file is existed
    with open('data/PanelBRY.dat', 'rb') as fp:
        PanelBRY = pickle.load(fp)
else:
    PanelBRY = [[0 for i in range(MaxPanelNum)] for j in range(MaxTaskNum)]

if os.path.exists('data/RoiUsed.dat') == True: # If the save file is existed
    with open('data/RoiUsed.dat', 'rb') as fp:
        RoiUsed = pickle.load(fp)
else:
    RoiUsed = [[0 for i in range(MaxRoiNum)] for j in range(MaxTaskNum)]
    RoiUsed[19][0] = 1

if os.path.exists('data/Roi1X.dat') == True: # If the save file is existed
    with open('data/Roi1X.dat', 'rb') as fp:
        Roi1X = pickle.load(fp)
else:
    #Roi1X = [[100 for i in range(MaxRoiNum)] for j in range(MaxTaskNum)]
    for i in range(MaxTaskNum):
        for i2 in range(MaxRoiNum):
            Roi1X[i][i2] = 20 * (i2 + 1)

if os.path.exists('data/Roi1Y.dat') == True: # If the save file is existed
    with open('data/Roi1Y.dat', 'rb') as fp:
        Roi1Y = pickle.load(fp)
else:
    for i in range(MaxTaskNum):
        for i2 in range(MaxRoiNum):
            Roi1Y[i][i2] = 100

if os.path.exists('data/Roi2X.dat') == True: # If the save file is existed
    with open('data/Roi2X.dat', 'rb') as fp:
        Roi2X = pickle.load(fp)
else:
    for i in range(MaxTaskNum):
        for i2 in range(MaxRoiNum):
            Roi2X[i][i2] = 20 * (i2 + 1)

if os.path.exists('data/Roi2Y.dat') == True: # If the save file is existed
    with open('data/Roi2Y.dat', 'rb') as fp:
        Roi2Y = pickle.load(fp)
else:
    for i in range(MaxTaskNum):
        for i2 in range(MaxRoiNum):
            Roi2Y[i][i2] = 140

if os.path.exists('data/LightThList.dat') == True: # If the save file is existed
    with open('data/LightThList.dat', 'rb') as fp:
        LightThList = pickle.load(fp)
else:
    LightThList = [[80 for i in range(MaxRoiNum)] for j in range(MaxTaskNum)]
    for i in range(MaxTaskNum):  #
        LightThList[i][19]=150
for i in range(MaxTaskNum):  #
    for i2 in range(MaxRoiNum):
        LightThListVar[i][i2].set(str(LightThList[i][i2]))

if os.path.exists('data/DarkThList.dat') == True: # If the save file is existed
    with open('data/DarkThList.dat', 'rb') as fp:
        DarkThList = pickle.load(fp)
else:
    DarkThList = [[80 for i in range(MaxRoiNum)] for j in range(MaxTaskNum)]
    for i in range(MaxTaskNum):  #
        DarkThList[i][19]=230
for i in range(MaxTaskNum):  #
    for i2 in range(MaxRoiNum):
        DarkThListVar[i][i2].set(str(DarkThList[i][i2]))

if os.path.exists('data/NumThList.dat') == True: # If the save file is existed
    with open('data/NumThList.dat', 'rb') as fp:
        NumThList = pickle.load(fp)
else:
    NumThList = [[6 for i in range(MaxRoiNum)] for j in range(MaxTaskNum)]
for i in range(MaxTaskNum):  #
    for i2 in range(MaxRoiNum):
        NumThListVar[i][i2].set(str(NumThList[i][i2]))
#Setting 1
if os.path.exists('data/RecipientAddress.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/RecipientAddress.dat', 'rb') as fp:
        RecipientAddressVar.set(pickle.load(fp))
else:
    RecipientAddressVar.set('')

if os.path.exists('data/SenderAddress.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/SenderAddress.dat', 'rb') as fp:
        SenderAddressVar.set(pickle.load(fp))
else:
    SenderAddressVar.set('operanthousepractice@gmail.com')

if os.path.exists('data/SenderPassword.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/SenderPassword.dat', 'rb') as fp:
        SenderPasswordVar.set(pickle.load(fp))
else:
    SenderPasswordVar.set('jyefthsomoavgmvf')

if os.path.exists('data/SmtpServer.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/SmtpServer.dat', 'rb') as fp:
        SmtpServerVar.set(pickle.load(fp))
else:
    SmtpServerVar.set('smtp.gmail.com')
if os.path.exists('data/SmtpPort.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/SmtpPort.dat', 'rb') as fp:
        SmtpPortVar.set(pickle.load(fp))
else:
    SmtpPortVar.set('587')
if os.path.exists('data/SecurityType.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/SecurityType.dat', 'rb') as fp:
        SecurityTypeVar.set(pickle.load(fp))
else:
    SecurityTypeVar.set('TLS')

if os.path.exists('data/DeviceName.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/DeviceName.dat', 'rb') as fp:
        DeviceNameVar.set(pickle.load(fp))
else:
    DeviceNameVar.set('Device1')
if os.path.exists('data/ArduinoConnection.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/ArduinoConnection.dat', 'rb') as fp:
        ArduinoConnectionVar.set(pickle.load(fp))
else:
    ArduinoConnectionVar.set('ON')
if os.path.exists('data/MouseDebugMode.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/MouseDebugMode.dat', 'rb') as fp:
        MouseDebugModeVar.set(pickle.load(fp))
else:
    MouseDebugModeVar.set('OFF')
if os.path.exists('data/CameraCaptureFreq.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/CameraCaptureFreq.dat', 'rb') as fp:
        CameraCaptureFreqVar.set(pickle.load(fp))
else:
    CameraCaptureFreqVar.set('1')

if os.path.exists('data/PanelTexturePath.dat') == True:  # Bottom right Y coordinate of nose poke detection ROI
    with open('data/PanelTexturePath.dat', 'rb') as fp:
        PanelTexturePath = pickle.load(fp)
else:
    PanelTexturePath = ['']*4

if os.path.exists('data/TaskStartTime1.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/TaskStartTime1.dat', 'rb') as fp:
        TaskStartTime1Var.set(pickle.load(fp))
else:
    TaskStartTime1Var.set('0:00')
if os.path.exists('data/TaskStartTime2.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/TaskStartTime2.dat', 'rb') as fp:
        TaskStartTime2Var.set(pickle.load(fp))
else:
    TaskStartTime2Var.set('')
if os.path.exists('data/TaskStartTime3.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/TaskStartTime3.dat', 'rb') as fp:
        TaskStartTime3Var.set(pickle.load(fp))
else:
    TaskStartTime3Var.set('')
if os.path.exists('data/TaskStartTime4.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/TaskStartTime4.dat', 'rb') as fp:
        TaskStartTime4Var.set(pickle.load(fp))
else:
    TaskStartTime4Var.set('')

if os.path.exists('data/LightPhaseOnsetTime.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/LightPhaseOnsetTime.dat', 'rb') as fp:
        LightPhaseOnsetTimeVar.set(pickle.load(fp))
else:
    LightPhaseOnsetTimeVar.set('9:00')
if os.path.exists('data/DarkPhaseOnsetTime.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/DarkPhaseOnsetTime.dat', 'rb') as fp:
        DarkPhaseOnsetTimeVar.set(pickle.load(fp))
else:
    DarkPhaseOnsetTimeVar.set('21:00')

if os.path.exists('data/MovieWidth.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/MovieWidth.dat', 'rb') as fp:
        MovieWidthVar.set(pickle.load(fp))
else:
    MovieWidthVar.set('320')

if os.path.exists('data/MovieHeight.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/MovieHeight.dat', 'rb') as fp:
        MovieHeightVar.set(pickle.load(fp))
else:
    MovieHeightVar.set('240')

if os.path.exists('data/RecordFps.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/RecordFps.dat', 'rb') as fp:
        RecordFpsVar.set(pickle.load(fp))
else:
    RecordFpsVar.set('12')

if os.path.exists('data/CamExposureLight.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/CamExposureLight.dat', 'rb') as fp:
        CamExposureLightVar.set(pickle.load(fp))
else:
    if RaspberryMode == 0:
        CamExposureLightVar.set('-8')
    if RaspberryMode == 1:
        CamExposureLightVar.set('1')

if os.path.exists('data/CamExposureDark.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/CamExposureDark.dat', 'rb') as fp:
        CamExposureDarkVar.set(pickle.load(fp))
else:
    if RaspberryMode == 0:
        CamExposureDarkVar.set('-6')
    if RaspberryMode == 1:
        CamExposureDarkVar.set('32')

if os.path.exists('data/PlayBackFps.dat') == True: # Bottom right Y coordinate of nose poke detection ROI
    with open('data/PlayBackFps.dat', 'rb') as fp:
        PlayBackFpsVar.set(pickle.load(fp))
else:
    PlayBackFpsVar.set('30')

if os.path.exists('data/CableDetectCorrValue.dat') == True: #
    with open('data/CableDetectCorrValue.dat', 'rb') as fp:
         CableDetectCorrValueVar.set(pickle.load(fp))
else:
    CableDetectCorrValueVar.set('0')

#Setting 2
if os.path.exists('data/RoiDensity.dat') == True: # If the save file is existed
    with open('data/RoiDensity.dat', 'rb') as fp:
        RoiDensityVar.set(pickle.load(fp))
else:
    RoiDensityVar.set('40') #10 20
RoiDensity = float(RoiDensityVar.get())

if os.path.exists('data/TouchOffTime.dat') == True: # If the save file is existed
    with open('data/TouchOffTime.dat', 'rb') as fp:
        TouchOffTimeVar.set(pickle.load(fp))
else:
    TouchOffTimeVar.set('1')

#CopyROI
if os.path.exists('data/CopyRoiFrom.dat') == True: # If the save file is existed
    with open('data/CopyRoiFrom.dat', 'rb') as fp:
        CopyRoiFromVar.set(pickle.load(fp))
else:
    CopyRoiFromVar.set('2')

if os.path.exists('data/CopyRoiTo1.dat') == True: # If the save file is existed
    with open('data/CopyRoiTo1.dat', 'rb') as fp:
        CopyRoiTo1Var.set(pickle.load(fp))
else:
    CopyRoiTo1Var.set('4')

if os.path.exists('data/CopyRoiTo2.dat') == True: # If the save file is existed
    with open('data/CopyRoiTo2.dat', 'rb') as fp:
        CopyRoiTo2Var.set(pickle.load(fp))
else:
    CopyRoiTo2Var.set('22')

if os.path.exists('data/CopyRoiTo3.dat') == True: # If the save file is existed
    with open('data/CopyRoiTo3.dat', 'rb') as fp:
        CopyRoiTo3Var.set(pickle.load(fp))
else:
    CopyRoiTo3Var.set('23')

if os.path.exists('data/CopyRoiTo4.dat') == True: # If the save file is existed
    with open('data/CopyRoiTo4.dat', 'rb') as fp:
        CopyRoiTo4Var.set(pickle.load(fp))
else:
    CopyRoiTo4Var.set('')

SetLightCycleTime()
TouchWindowRoot.bind('<Motion>', motion)
ret, Img = VideoCapture.read()    #Capture video frame
cv2.imshow("CameraWindow", Img)  # Show captured video frame
CapturedImgSize=np.shape(Img)

CapturedImgWidth = CapturedImgSize[1]
CapturedImgHeight = CapturedImgSize[0]
print("Captured camera resolution: x "+str(CapturedImgWidth)+" y "+str(CapturedImgHeight))
#mouseData = mouseParam("CameraWindow") # Instantiate class for get mouse cursor coordinates of camera window
Timer_Start(4)  # Timer for servo power
#ser.flush()

RemoveAllServoGui()
PutServoGui(3)
#PutServoGui(5)
RemoveAllDigitalOutGui()
PutDigitalOutGui(10)
PutDigitalOutGui(12)
PutDigitalOutGui(13)

while EndFlag<=4: # Main roop of non-task period 3
    OperantHouseUpdate()
    if OHCnt==1:
        ServoWindowRoot.geometry('+'+str(ServoWindowPosX)+'+'+str(ServoWindowPosY))  #100,300  '+100+300'
        DOutWindowRoot.geometry('+'+str(DOutWindowPosX)+'+'+str(DOutWindowPosY))  #100,300  '+100+300'
        RoiWindowRoot.geometry('+'+str(RoiWindowPosX)+'+'+str(RoiWindowPosY))
    if OHCnt==30:    # If it takes a while after running (Serial connection doesn't establish at the 1st frame)
        RoofLightOn()    #Turn on roof illumination
        InfraredLightOn()    # Turn on IR illumination
        ServoPosMiddle(3)  # Move water nozzle to the intermediate position
    if ButtonAWS_On==1: # If button activated AWS is turned on
        if AWS_Stat==1:
            ServoPosMiddle(3)
            DigitalOutOff(10)
            RoofLightOn()
            IsWaterCueBlink = 0
            ButtonAWS_On=0
    if EndFlag==3:  # If LEDs are turned off and water nozzle move to neutral position, turn off the switch of servo
        Angle = 127  # Means make servo is turned off (ValueRange=0-127(0-180 degree))
        ServoOutputBook = 1

SaveGeneralParameter()
time.sleep(0.5) # Wait to make sure to torun of servo
if DebugWithoutArduinoMode==0:
    ser.close()


#VideoWriter.release()
if DuringCameraReset==0:
    VideoCapture.release()
cv2.destroyAllWindows()
quit()