Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Analogue fix #2

Open
wants to merge 98 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
4064983
Add system import
warnerwarner Dec 11, 2018
80367f3
Add randomise trials and anti plume
warnerwarner Jan 17, 2019
29b37d9
fixed randomisation
warnerwarner Jan 17, 2019
2f2d741
Add anti plume widget
warnerwarner Jan 17, 2019
b1136dd
Add some ipython notebooks for testing
warnerwarner Jun 18, 2019
2a38e14
Add binary widget
warnerwarner Jun 18, 2019
e3ada12
Add binary valve type to main
warnerwarner Jun 18, 2019
a881946
Merge branch 'master' of https://github.com/warnerwarner/PulseBoy
warnerwarner Jun 18, 2019
213eed3
Add binary valve type
warnerwarner Jun 19, 2019
b0a85d8
Add binary valve backend
warnerwarner Jun 19, 2019
a58ae23
Rename binary valve widget
warnerwarner Jun 19, 2019
8987aee
add s to make class
warnerwarner Jun 19, 2019
410a8d6
cast datapath to string
warnerwarner Jun 19, 2019
28acdaa
Comment out path insertion
warnerwarner Jun 19, 2019
a4b288c
Merge branch 'master' of https://github.com/warnerwarner/PulseBoy
warnerwarner Jun 19, 2019
5927421
add paths
warnerwarner Jul 4, 2019
38f881a
Add triggered co task support
warnerwarner Jul 11, 2019
32a8ae9
Add random extra lines
warnerwarner Jul 11, 2019
97b5380
Merge branch 'master' of https://github.com/warnerwarner/PulseBoy
warnerwarner Jul 11, 2019
e643cfe
update for binary pulse
warnerwarner Jul 12, 2019
b6b6dc9
Merge branch 'master' of https://github.com/warnerwarner/PulseBoy
warnerwarner Jul 12, 2019
25468a8
remove binary load and floating a float
warnerwarner Jul 12, 2019
30b7dc0
add test binary trialbank
warnerwarner Jul 12, 2019
89a6c88
Merge branch 'master' of https://github.com/warnerwarner/PulseBoy
warnerwarner Jul 12, 2019
388b28c
update test trialbank
warnerwarner Jul 12, 2019
675f4b7
add second test trialbank
warnerwarner Jul 12, 2019
cedb949
update binary_test_trialbank
warnerwarner Jul 12, 2019
ff2f753
even more test trialbanks
warnerwarner Jul 12, 2019
b135151
another test trialbank
warnerwarner Jul 12, 2019
a10d7f6
another trialbank
warnerwarner Jul 12, 2019
bd39fda
add shatter to binary pulse
warnerwarner Jul 12, 2019
30fe843
Merge branch 'master' of https://github.com/warnerwarner/PulseBoy
warnerwarner Jul 12, 2019
55e30c6
new trialbanks
warnerwarner Jul 12, 2019
4c32b9a
Merge branch 'master' of https://github.com/warnerwarner/PulseBoy
warnerwarner Jul 12, 2019
14bd28a
add trialbank
warnerwarner Jul 12, 2019
4b04cb2
more trialbanks
warnerwarner Jul 12, 2019
03673f8
update trialbank
warnerwarner Jul 12, 2019
1463f6e
new trialbank
warnerwarner Jul 12, 2019
ac052ce
Add position of valve
warnerwarner Aug 21, 2019
ac3d1ea
Cast position to str
warnerwarner Aug 22, 2019
f60559b
attempt to indepently update valve
warnerwarner Aug 22, 2019
0522176
cast to string and add position to init
warnerwarner Aug 22, 2019
1b31711
remove the main alterations
warnerwarner Aug 22, 2019
4b8fa84
make sure position passed to right argument
warnerwarner Aug 22, 2019
a418938
readjust argument order
warnerwarner Aug 22, 2019
11a6592
update get and set params
warnerwarner Aug 22, 2019
9a2acc8
Add position for all valve types
warnerwarner Aug 22, 2019
a9b0a8a
Cast to string (again)
warnerwarner Aug 22, 2019
ed405f9
update the intial position
warnerwarner Aug 22, 2019
f6318ae
added run from selected support
warnerwarner Aug 22, 2019
90093a5
valve widget numbering and start queue from selected
warnerwarner Aug 22, 2019
1c432ef
Merge branch 'master' of https://github.com/warnerwarner/PulseBoy
warnerwarner Aug 22, 2019
5168aa8
Update loading trialbank to have positions
warnerwarner Aug 23, 2019
e013c86
Merge branch 'master' of https://github.com/warnerwarner/PulseBoy
warnerwarner Aug 23, 2019
8374773
testing trialbank loading
warnerwarner Aug 23, 2019
9bc90bd
Create README.md
warnerwarner Jan 7, 2020
1f3742e
Update README.md
warnerwarner Jan 7, 2020
842f3dd
Add binary pulse shattering
warnerwarner Feb 25, 2020
4b8ab50
Merge branch 'master' of https://github.com/warnerwarner/PulseBoy
warnerwarner Feb 25, 2020
4ad5265
change to data saving
warnerwarner Feb 27, 2020
0ec0499
change path
warnerwarner Feb 27, 2020
db09f28
Merge branch 'data_saving' of https://github.com/warnerwarner/PulseBo…
warnerwarner Feb 27, 2020
01eb596
Write trial names to file
warnerwarner Feb 27, 2020
5724364
add intial trialbank repeats
warnerwarner Feb 27, 2020
a4fc8ec
Save trial name and time of repeat start
warnerwarner Feb 27, 2020
4735a30
add repeat print
warnerwarner Feb 27, 2020
7fe14fa
Merge pull request #1 from warnerwarner/data_saving
warnerwarner Nov 25, 2020
c62e3b8
New camera tab
warnerwarner Dec 1, 2020
ea3c2b5
added camera support
warnerwarner Dec 2, 2020
29e5230
allows stream to close on its own
warnerwarner Dec 2, 2020
ccb8804
Remove shatter duty reset
warnerwarner Dec 7, 2020
5ba3f38
Add invert valves box
warnerwarner Feb 19, 2021
81eb4d6
Add invert valve rest state
warnerwarner Feb 19, 2021
4f1ad72
Merge branch 'master' of https://github.com/warnerwarner/PulseBoy
warnerwarner Feb 19, 2021
ca24645
Try and catch in case blank valves empty
warnerwarner Feb 19, 2021
a981bfc
Add inverted channels to queuecontroller
warnerwarner Feb 19, 2021
e2c43ea
close valves after trial
warnerwarner Feb 22, 2021
0b6b4c1
init close_valves
warnerwarner Feb 22, 2021
912d1a6
add valve close button
warnerwarner Feb 22, 2021
adc3a63
remove additional function
warnerwarner Feb 22, 2021
404b414
close valve function rename
warnerwarner Feb 23, 2021
b1151ff
add shuffle trial parameters
warnerwarner Mar 1, 2021
31524b2
Add shuffle parameter back end
warnerwarner Mar 1, 2021
1ab6fed
Merge branch 'master' of https://github.com/warnerwarner/PulseBoy
warnerwarner Mar 1, 2021
9381b3b
shuffle index fix
warnerwarner Mar 1, 2021
c61cdd7
vipulse warning print
warnerwarner Mar 1, 2021
dc8b622
add shuffle tick box fix
warnerwarner Mar 2, 2021
91ea134
old binary pulse fix attempt
warnerwarner Mar 2, 2021
ce75016
stop binary being force shattered
warnerwarner Mar 2, 2021
6fa9151
increase number of repetitions to 1mil
warnerwarner Apr 6, 2021
aecca2f
increase reps to 1million
warnerwarner Apr 6, 2021
7c30c9d
Add carrier flow hardware param
warnerwarner Apr 14, 2021
07cd013
carrier flow edits
warnerwarner May 3, 2021
12493c2
Merge remote-tracking branch 'upstream/master'
warnerwarner Feb 3, 2022
efb252a
back offset
warnerwarner Feb 17, 2022
9fd890f
main design back offset
warnerwarner Feb 17, 2022
4620ab1
end trig fix
warnerwarner Feb 17, 2022
5ae5cda
shuffle back offset fix 1
warnerwarner Mar 8, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ Data/
>>>>>>> 73c6c9b7133534e9970e82c3c355c6f2e3fd1194
TestData/020217_right_25_2_export_final.mat
TrialBanks/
Controllers/dist
Controllers/build
7,083 changes: 7,083 additions & 0 deletions .ipynb_checkpoints/Binary sequence creating-checkpoint.ipynb

Large diffs are not rendered by default.

4,831 changes: 4,831 additions & 0 deletions .ipynb_checkpoints/Plume_analysis.py-checkpoint.ipynb

Large diffs are not rendered by default.

7,083 changes: 7,083 additions & 0 deletions Binary sequence creating.ipynb

Large diffs are not rendered by default.

86 changes: 69 additions & 17 deletions Controllers/QueueControl.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from PyPulse import PulseInterface
import scipy.io as sio
import numpy as np
from datetime import datetime


class QueueWorker(QtCore.QObject):
Expand All @@ -29,44 +30,86 @@ def trial(self):
hardware_params = self.get_hardware_params()
global_params = self.get_global_params()
export_params = self.get_export_params()

invert_valves = []
if global_params['inverted_blank_off_state']:
invert_valves = global_params['inverted_blank_valves']
pulses, t = PulseInterface.make_pulse(hardware_params['samp_rate'],
global_params['global_onset'],
global_params['global_offset'],
trial_params)
trial_params, invert_chan_list=invert_valves)

if hardware_params['control_carrier']:
while len(pulses) < hardware_params['digital_channels']:
pulses = np.append(pulses, np.zeros((1, pulses.shape[1])), axis=0)
carrier_control = np.append(np.ones(pulses.shape[1]-0), np.zeros(0))
pulses = np.append(pulses, carrier_control[np.newaxis], axis=0)
# in standard configuration we want to run each trial sequentially
if not self.parent.trigger_state():
self.trial_daq = daq.DoAiMultiTask(hardware_params['analog_dev'], hardware_params['analog_channels'],
hardware_params['digital_dev'], hardware_params['samp_rate'],
len(t) / hardware_params['samp_rate'], pulses,
hardware_params['sync_clock'])

self.analog_data = self.trial_daq.DoTask()
if hardware_params['analog_channels'] > 0:
self.trial_daq = daq.DoAiMultiTask(hardware_params['analog_dev'], hardware_params['analog_channels'],
hardware_params['digital_dev'], hardware_params['samp_rate'],
len(t) / hardware_params['samp_rate'], pulses,
hardware_params['sync_clock'])

self.analog_data = self.trial_daq.DoTask()
else:
self.trial_daq = daq.DoCoTask(hardware_params['digital_dev'], '', hardware_params['samp_rate'],
len(t) / hardware_params['samp_rate'], pulses)
self.trial_daq.DoTask()
# close_valves= daq.DoCoTask(hardware_params['digital_dev'], '', hardware_params['samp_rate'],
# len(t) / hardware_params['samp_rate'], np.zeros((len(pulses), 10)))
# close_valves.DoTask()
self.analog_data = []
# unless the 'wait for trigger' box is checked, in which case we want to wait for our trigger in
else:
self.trial_daq = daq.DoAiTriggeredMultiTask(hardware_params['analog_dev'],
if hardware_params['analog_channels'] > 0 :
self.trial_daq = daq.DoAiTriggeredMultiTask(hardware_params['analog_dev'],
hardware_params['analog_channels'],
hardware_params['digital_dev'],
hardware_params['samp_rate'],
len(t) / hardware_params['samp_rate'], pulses,
hardware_params['sync_clock'],
hardware_params['trigger_source'])

self.analog_data = self.trial_daq.DoTask()
self.analog_data = self.trial_daq.DoTask()
else:
self.trial_daq= daq.DoTriggeredCoTask(hardware_params['digital_dev'], '', hardware_params['samp_rate'], len(t) / hardware_params['samp_rate'],
pulses, hardware_params['trigger_source'])
self.trial_daq.DoTask()
self.analog_data = []

# Save data
save_string = export_params['export_path'] + str(self.experiment.current_trial) + \
export_params['export_suffix'] + '.mat'
sio.savemat(save_string, {'analog_data': self.analog_data, 'pulses': pulses, 't': t})
if export_params['save_pulses']:
save_string = export_params['export_path'] + str(self.experiment.current_trial) + \
export_params['pulse_suffix'] + '.mat'
sio.savemat(save_string, {'analog_data': self.analog_data, 'pulses': pulses, 't': t})


if self.experiment.total_trials() - self.experiment.current_trial == 1:
self.parent.should_run = False
self.experiment.reset_trials()

if self.parent.should_run:
if export_params['save_names']:
names = [i[-1] for i in self.experiment.arraydata]
date = datetime.today().strftime('%Y-%m-%d')
time = datetime.today().strftime('%H:%M:%S')
f = open(export_params['export_path']+date+export_params['trial_suffix']+'.txt', 'a')
f.write(time)
f.write('\n')
f.write('\n'.join(names))
f.write('\n')
f.close()
self.parent.repeats_done += 1
print('repeats done ', self.parent.repeats_done)
if self.parent.repeats_done == global_params['repeats']:
self.parent.should_run = False
self.parent.repeats_done = 0
else:
if global_params['shuffle_repeats']:
self.experiment.randomise_trials(global_params)

elif self.parent.should_run:
self.experiment.advance_trial()


self.finished.emit()


Expand All @@ -80,6 +123,7 @@ def __init__(self, experiment, get_global_params, get_hardware_params, get_expor
self.get_hardware_params = get_hardware_params
self.get_export_params = get_export_params
self.prepare_thread()
self.repeats_done = 0

self.should_run = False
self.trigger_control = trigger_control
Expand All @@ -95,6 +139,7 @@ def prepare_thread(self):
self.thread.start()

def start(self):

if not self.should_run:
self.should_run = True

Expand All @@ -108,6 +153,8 @@ def stop(self):
self.should_run = False

self.experiment.reset_trials()
self.repeats_done = 0


def run_selected(self, trial):
if not self.should_run:
Expand All @@ -116,9 +163,14 @@ def run_selected(self, trial):
sleep(0.05)
self.should_run = False

def run_from_selected(self, trial):
if not self.should_run:
self.should_run = True
self.experiment.current_trial = trial


def finished(self):
print("not implemented")

def trigger_state(self):
return self.trigger_control.isChecked()

117 changes: 109 additions & 8 deletions Controllers/main.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import sys
sys.path.append('C:\\Users\\warnert\\Documents\\GitHub')
sys.path.append('C:\\Users\\warnert\\Documents\\GitHub\\PulseBoy_updated\\PulseBoy')
sys.path.append('C:\\Users\\warnert\\Documents\\GitHub\\PulseBoy')

from PyPulse import PulseInterface
import numpy as np
from PyQt5 import QtWidgets

import Models.Experiment as Experiment
from Controllers import QueueControl, QueueControl
from multiprocessing import Queue, Process, Manager
from Designs import mainDesign
from Models import PBWidgets
try:
from vipulse import StreamNSave
except ImportError:
print('No camera!')
import pickle as pickle
import os.path
import daqface.DAQ as daq


# noinspection PyBroadException
Expand Down Expand Up @@ -44,6 +52,7 @@ def __init__(self):
self.removeTrialButton.clicked.connect(self.remove_trial)
self.moveUpButton.clicked.connect(self.move_trial_up)
self.moveDownButton.clicked.connect(self.move_trial_down)
self.randomiseTrialsButton.clicked.connect(self.randomise_trials)

self.actionSave.triggered.connect(self.save)
self.actionLoad.triggered.connect(self.load)
Expand All @@ -58,21 +67,44 @@ def __init__(self):
self.stopQueueButton.clicked.connect(self.queue_controller.stop)
self.pauseQueueButton.clicked.connect(self.queue_controller.pause)
self.runSelectedButton.clicked.connect(lambda x: self.queue_controller.run_selected(self.trialBankTable.selectionModel().selectedRows()[0].row()))
self.startQueueFromSelectedButton.clicked.connect(lambda x: self.queue_controller.run_from_selected(self.trialBankTable.selectionModel().selectedRows()[0].row()))

## Camera code
camera_params = Manager().dict()
self.cameraParams = camera_params
self.launchCameraButton.clicked.connect(self.startStream)

self.get_camera_params()
self.closeCamerasButton.clicked.connect(self.terminateCameraStream)
self.updateCamerasButton.clicked.connect(self.get_camera_params)
self.closeValvesButton.clicked.connect(self.reset_all_chans)

## Saving pulses
self.savePulseButton.clicked.connect(self.save_all_pulses)


def add_valve(self, v_type='Simple', params=None):
position = len(self.valveBankContents.children()) - 1
if v_type == 'Simple':
new_valve = PBWidgets.SimpleValveWidget(self.valveBankContents)
new_valve = PBWidgets.SimpleValveWidget(self.valveBankContents, position)
elif v_type == 'Noise':
new_valve = PBWidgets.NoiseValveWidget(self.valveBankContents)
new_valve = PBWidgets.NoiseValveWidget(self.valveBankContents, position)
elif v_type == 'Plume':
new_valve = PBWidgets.PlumeValveWidget(self.valveBankContents)
new_valve = PBWidgets.PlumeValveWidget(self.valveBankContents, position)
elif v_type == 'Anti Plume':
new_valve = PBWidgets.AntiPlumeValveWidget(self.valveBankContents, position)
elif v_type == 'Binary':
new_valve = PBWidgets.BinaryPlumeValveWidget(self.valveBankContents, position)
else:
new_valve = PBWidgets.SimpleValveWidget(self.valveBankContents)
new_valve = PBWidgets.SimpleValveWidget(self.valveBankContents, position)

if params is not None:
new_valve.set_parameters(params)
self.valveBankContents.layout().addWidget(new_valve)

def reset_all_chans(self):
daq.closeValves(self.get_hardware_params()['digital_dev'])

def add_trial(self):
n_valves = 0
all_params = list()
Expand Down Expand Up @@ -120,17 +152,27 @@ def move_trial_down(self):
if idx < len(self.trialBankModel.arraydata):
self.select_trial(idx + 1)

def randomise_trials(self):
glob_params = self.get_global_params()
self.trialBankModel.randomise_trials(glob_params)

def trial_selected(self):
try:
selected_trial = self.trialBankTable.selectionModel().selectedRows()[0].row()
except:
selected_trial = 0

trial_params = self.trialBankModel.arraydata[selected_trial][1]

invert_valves = []
if self.invertBlankcheckBox.isChecked():
try:
invert_valves = [int(i) for i in self.blankValveEdit.text().split(',')]
except ValueError:
print('Unable to invert channels, did not understand input "%s' % self.blankValveEdit.text())

pulses, t = PulseInterface.make_pulse(float(self.sampRateEdit.text()),
float(self.globalOnsetEdit.text()),
float(self.globalOffsetEdit.text()), trial_params)
float(self.globalOffsetEdit.text()), trial_params, invert_chan_list=invert_valves)

self.graphicsView.plotItem.clear()
for p, pulse in enumerate(pulses):
Expand Down Expand Up @@ -211,26 +253,85 @@ def get_hardware_params(self):
params['sync_clock'] = self.syncClockEdit.text()
params['samp_rate'] = float(self.sampRateEdit.text())
params['trigger_source'] = self.triggerInEdit.text()
params['control_carrier'] = self.carrierControlBox.isChecked()
# params['carrier_chan'] = int(self.carrierDeviceEdit.text())

return params

def get_global_params(self):
params = dict()
params['global_onset'] = float(self.globalOnsetEdit.text())
params['global_offset'] = float(self.globalOffsetEdit.text())
params['repeats'] = float(self.repeatsBox.text())
#params['repeats_done'] = 0
params['shuffle_repeats'] = bool(self.shuffleRepeatsBox.isChecked())
params['inverted_blank_off_state'] = bool(self.invertBlankcheckBox.isChecked())
if params['inverted_blank_off_state']:
params['inverted_blank_valves'] = [int(i) for i in self.blankValveEdit.text().split(',')]
else:
params['inverted_blank_valves'] = None

params['shuffle_offset'] = int(self.shuffleOffsetlineEdit.text())
params['shuffle_group_size'] = int(self.shuffleGrouplineEdit.text())
params['shuffle_back_offset'] = int(self.shuffleBackOffsetlineEdit.text())
return params

def get_export_params(self):
params = dict()
params['save_names'] = bool(self.trialNameCheckBox.isChecked())
params['save_pulses'] = bool(self.pulseCheckBox.isChecked())
params['export_path'] = str(self.exportPathEdit.text())
params['export_suffix'] = str(self.exportSuffixEdit.text())
params['pulse_suffix'] = str(self.pulseSuffixEdit.text())
params['trial_suffix'] = str(self.trialNameSuffixEdit.text())

return params

def set_export_path(self):
path = QtWidgets.QFileDialog.getExistingDirectory(self, "Choose Export Path")
self.exportPathEdit.setText(path + '/')


def startStream(self):
self.get_camera_params()
self.cameraParams['runStream'] = True
self.cameraProcess = Process(target=StreamNSave.stream_and_save,
args=(self.cameraParams,))
self.cameraProcess.daemon = True
self.cameraProcess.start()
def terminateCameraStream(self):
self.cameraParams['runStream'] = False
#self.cameraProcess.terminate()

def get_camera_params(self):
self.cameraParams['saveStream'] = bool(self.saveCameraVideocheckBox.isChecked())
self.cameraParams['showStream'] = bool(self.showStreamcheckBox.isChecked())
self.cameraParams['outDir'] = str(self.exportPathEdit.text())
self.cameraParams['cams'] = int(self.numberCamerasEdit.text())
self.cameraParams['cameraSuffix'] = str(self.cameraSuffixEdit.text())
self.cameraParams['inter_stream_interval'] = float(self.cameraSaveIntervalEdit.text())
self.cameraParams['recording_ind'] = bool(self.cameraSaveIconBox.isChecked())

def save_all_pulses(self):
global_params = self.get_global_params()
hardware_params = self.get_hardware_params()
export_params = self.get_export_params()
invert_valves = []
all_pulses = {}
for trial_params in self.trialBankModel.arraydata:
pulses, t = PulseInterface.make_pulse(hardware_params['samp_rate'],
global_params['global_onset'],
global_params['global_offset'],
trial_params[1])
save_string = export_params['export_path'] + trial_params[-1] + '_'+export_params['pulse_suffix'] + '.npy'
np.save(save_string, pulses)
all_pulses[trial_params[-1]] = pulses
save_string = export_params['export_path'] + export_params['pulse_suffix'] + '.pkl'
#pickle.dump(all_pulses, open(save_string, 'wb'), protocol=pickle.HIGHEST_PROTOCOL)






# Back up the reference to the exceptionhook
sys._excepthook = sys.excepthook
Expand Down
Loading