diff --git a/+eui/SignalsTest.m b/+eui/SignalsTest.m
index 6a66a272..0567ace5 100644
--- a/+eui/SignalsTest.m
+++ b/+eui/SignalsTest.m
@@ -118,6 +118,16 @@
'signals:test:copyPaths',...
'No paths file found. A template can be found in %s.', ...
fullfile(fileparts(which('addRigboxPaths')), 'docs', 'setup'))
+
+ % Check that the Psychophisics Toolbox is installed
+ toolboxes = ver;
+ isInstalled = strcmp('Psychtoolbox', {toolboxes.Name});
+ if ~any(isInstalled) || str2double(toolboxes(isInstalled).Version(1)) < 3
+ error('signals:test:toolboxRequired',...
+ ['Requires Psychtoolbox v3.0 or higher to be installed. '...
+ 'Follow the steps in the README to install.'],...
+ 'https://github.com/cortex-lab/Rigbox/tree/master#installing-psychtoolbox')
+ end
obj.LastDir = getOr(dat.paths, 'expDefinitions');
if nargin > 0 % called with experiment function to run
diff --git a/+exp/Parameters.m b/+exp/Parameters.m
index 04efe1c8..18745912 100644
--- a/+exp/Parameters.m
+++ b/+exp/Parameters.m
@@ -38,6 +38,28 @@
end
function set(obj, name, value, description, units)
+ % SET Set a named parameter value
+ % SET(OBJ, NAME, VALUE[, DESCRIPTION, UNITS]) sets the value of a
+ % parameter. If the parameter doesn't already exist, a new one is
+ % added.
+ %
+ % Inputs:
+ % name (char): The parameter name to set
+ % value: The value of the parameter. The number of columns must
+ % be 1 or equal to numTrialConditions (or for chars the number
+ % of rows)
+ % description (char): Optional. A description of the parameter
+ % units (char): Optional. The parameter units
+ %
+ % Example 1: Add a new parameter called targetAltitude
+ % description = 'Visual angle of target centre above horizon';
+ % P.set('targetAltitude', 90, description, '°')
+ %
+ % Example 2: Set the values for a trial condition
+ % values = randsample(0:45:135, P.numTrialConditions, true);
+ % P.set('orientation', values)
+ %
+ % See also DESCRIPTION, NUMTRIALCONDITIONS
% if size(value, 2) > 1
% % Attempting to set a conditional parameter so it should match the
diff --git a/README.md b/README.md
index 8099a059..b8d00952 100644
--- a/README.md
+++ b/README.md
@@ -3,27 +3,40 @@
![Coverage badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fsilent-zebra-36.tunnel.datahub.at%2Fcoverage%2Frigbox%2Fmaster)
![Build status badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fsilent-zebra-36.tunnel.datahub.at%2Fstatus%2Frigbox%2Fmaster)
-Rigbox is a high-performance, open-source MATLAB toolbox for managing behavioral neuroscience experiments.
-Rigbox's main goals are to simplify hardware/software interfacing, behavioral task design, and visual and auditory stimuli presentation. Additionally, Rigbox can time-align datastreams from multiple sources and communicate with a remote database to manage experiment data. Rigbox is mostly object-oriented and highly modular, which simplifies the process of designing experiments.
+Rigbox is a high-performance, open-source MATLAB toolbox for managing behavioral neuroscience experiments. Initially developed to probe mouse behavior for the [Steering Wheel Setup](https://www.ucl.ac.uk/cortexlab/tools/wheel), Rigbox simplifies hardware/software interfacing and creates a runtime environment in which an experiment's parameters can be easily monitored and manipulated. Its many features include synchronizing recordings, managing experimental data and a viewing model for visual stimuli. Rigbox is mostly object-oriented and highly modular, making designing and extending experiments much simpler.
## Requirements
For exploring Rigbox's features and running test experiments, Rigbox only needs to be installed on a single computer.
-For running experiments, we recommend installing Rigbox on two computers: one computer (which we refer to as the "Stimulus Computer" or "SC") communicates with an experiment rig's hardware and presents stimuli, and the other computer (which we refer to as the "Master Computer" or "MC") runs a GUI that the experimenter can use to start, monitor, parameterize, and stop the experiment.
+Rigbox has the following software dependencies:
+* **OS:** Windows 7 or later, 64-bit
+* **MATLAB:** 2018b (v9.5) or later, with the Data Acquisition Toolbox
+* **Libraries**: [Visual C++ Redistributable Packages for Visual Studio 2013](https://www.microsoft.com/en-us/download/details.aspx?id=40784) & [2015-2019](https://github.com/Psychtoolbox-3/Psychtoolbox-3/raw/master/Psychtoolbox/PsychContributed/vcredist_x64_2015-2019.exe)
+* **MATLAB community toolboxes:**
+ * [GUI Layout Toolbox](https://uk.mathworks.com/matlabcentral/fileexchange/47982-gui-layout-toolbox) (v2 or later)
+ * [Psychophysics Toolbox](http://psychtoolbox.org/download.html) (v3 or later)
+ * [NI-DAQmx support package](https://uk.mathworks.com/hardware-support/nidaqmx.html) (Required if using an NI DAQ)
+
+Additionally, Rigbox works with a number of extra submodules (included with Rigbox):
+* [signals](https://github.com/cortex-lab/signals) (for designing bespoke experiments in Signals)
+* [alyx-matlab](https://github.com/cortex-lab/alyx-matlab) (for registering data to, and retrieving from, an [Alyx database](https://alyx.readthedocs.io/en/latest/))
+* [npy-matlab](https://github.com/kwikteam/npy-matlab) (for saving data in binary NPY format)
+* [wheelAnalysis](https://github.com/cortex-lab/wheelAnalysis) (for analyzing data from the steering wheel task)
### Hardware
-Below are the **minimum** computer hardware specs:
-* CPU: 4 logical processors @ 3.0 GHz base speed (e.g. Intel Core i5-6500)
-* RAM: DDR4 16 GB @ 2133 MHz (e.g. Corsair Vengeance 16 GB)
-* GPU: 2 GB @ 1000 MHz base and memory speed (e.g. NVIDIA Quadro P400)
+Below are a few minimum hardware requirements for both PCs. Precise requirements depend on the type of experiments you wish to run, however most contemporary PC with a dedicated graphics card should suffice.
-For most experiments, typical, contemporary, factory-built desktops running Windows 10 with dedicated graphics cards should suffice. Specific requirements of a SC will depend on the complexity of the experiment. For example, running an audio-visual integration task on multiple screens will require quality graphics and sound cards. SCs may additionally require an i/o device to communicate with external rig hardware, of which only National Instruments Data Acquisition Devices (NI-DAQs, e.g. NI-DAQ USB 6211) are currently supported.
+**Processor:** Intel Core i5-6500 @ 3.0 GHz (or similar)
+**Graphics:** NVIDIA Quadro P400 (or similar)
+**Memory:** DDR4 16 GB @ 2133 MHz (e.g. Corsair Vengeance 16 GB)
### Software
-Below are the **minimum** computer software dependencies that must be installed before installing Rigbox:
+Below are short instructions for installing Rigbox for users familiar with Git and MATLAB. For detailed instructions, please see the [installation guide](https://cortex-lab.github.io/Rigbox/install.html).
+
+Before starting, ensure the above toolboxes and packages are installed. PsychToobox can not be installed via the MATLAB AddOns browser. See [Installing PsychToobox](#Installing-PsychToolbox) for install instructions.
* OS: 64 Bit Windows 7 or later
* Libraries: Visual C++ Redistributable Packages for Visual Studio [2013](https://www.microsoft.com/en-us/download/details.aspx?id=40784) & [2015](https://www.microsoft.com/en-us/download/details.aspx?id=48145)
@@ -32,30 +45,40 @@ Below are the **minimum** computer software dependencies that must be installed
* [GUI Layout Toolbox](https://uk.mathworks.com/matlabcentral/fileexchange/47982-gui-layout-toolbox) (v2 or later)
* [Psychophysics Toolbox](http://psychtoolbox.org/download.html#Windows) (v3 or later)
-Similar to the hardware requirements, software requirements for a SC will depend on the experiment: if acquiring data through a NI-DAQ, the SC will require the MATLAB Data Acquisition Toolbox and MATLAB [NI-DAQmx support package](https://uk.mathworks.com/hardware-support/nidaqmx.html)
+1. To install Rigbox, run the following commands in the Git Bash terminal to clone the repository from GitHub to your local machine.
+```
+git clone --recurse-submodules https://github.com/cortex-lab/Rigbox
+```
+2. Run the `addRigboxPaths.m` function in MATLAB (found in the Rigbox directory) then restart the program. This adds all required folders and functions to your MATLAB path**. __NB__: Do __not__ manually add all Rigbox folders and subfolders to the paths
-## Installation
+\* Accepting all installer defaults will suffice.
+** To add the paths temporarily for testing, run `addRigboxPaths('SavePaths', false, 'Strict', false)`
Before starting, ensure you have read and followed the above [requirements section](#requirements).
Below we provide brief instructions for installing Rigbox via Git. For a detailed installation guide, including installing Rigbox's software dependencies, see [here](https://cortex-lab.github.io/Rigbox/detailed_installation.html).
-1. Clone the repository from GitHub. In your git terminal, run:
+1. Download and install a Subversion client. [SilkSVN](https://sliksvn.com/download/) is recommended.
+2. Download and install the [64-Bit GStreamer-1.16.0 MSVC runtime](https://gstreamer.freedesktop.org/data/pkg/windows/1.16.0/gstreamer-1.0-msvc-x86_64-1.16.0.msi). Make sure all offered packages are installed.
+3. Download the MATLAB [installer function](https://raw.githubusercontent.com/Psychtoolbox-3/Psychtoolbox-3/master/Psychtoolbox/DownloadPsychtoolbox.m) from the PsychToolbox GitHub page.
+4. Call the function in MATLAB with the target install location (folder must exist) and follow the instructions:
```
git clone --recurse-submodules https://github.com/cortex-lab/Rigbox
```
-2. Add all required Rigbox folders and functions to your MATLAB path. In MATLAB, navigate to the Rigbox root directory (where Rigbox was cloned), and run:
-`addRigboxPaths()`, OR `addRigboxPaths('SavePaths', false)` if you don't want to save the paths for future MATLAB sessions.
-(*Note*: Do **not** manually add all Rigbox folders and subfolders to the paths.)
-
## Getting started
+After following the installation instructions you can start playing around with Rigbox and Signals. To run one of the example experiments, open MATLAB and run `eui.SignalsTest();`, then select 'advancedChoiceWorld.m'.
+
+![](https://github.com/cortex-lab/Rigbox/blob/master/docs/html/images/SignalsTest%20GUI%20Example.gif)
+
+Full Rigbox documentation can be found at [cortex-lab.github.io/Rigbox](https://cortex-lab.github.io/Rigbox/).
+
+To run the example experiments from the Rigbox paper, see [Running Paper Examples](https://cortex-lab.github.io/Rigbox/paper_examples.html).
-Rigbox uses the *Signals* framework for programatically designing and running behavioral tasks.
-See the *Signals* [docs](https://github.com/cortex-lab/signals/tree/master/docs) for more information on *Signals* and how to run example test experiments on a single computer via Rigbox's `+eui/SignalsTest.m` GUI.
+For more infomation on using the Signals Test GUI see [this guide](https://cortex-lab.github.io/Rigbox/using_test_gui.html).
-![](https://github.com/cortex-lab/Rigbox/blob/master/docs/html/SignalsTest%20GUI%20Example.gif)
-(The above is an example of running the `signals/docs/examples/exp defs/advancedChoiceWorld.m` file in the `+eui/SignalsTest.m` GUI)
+### Running an experiment
+For running full experiments see the [Setting up experiments](https://cortex-lab.github.io/Rigbox/index.html#2) guide. This will guide you through configuring a visual viewing model, configuring audio devices and setting up hardware that requires a DAQ.
For information on running experiments via MC and SC, see Rigbox's [index page](https://github.com/cortex-lab/Rigbox/blob/dev/docs/html/index.html). This page also contains information on setting up Rigbox (see also [`docs/setup`](https://github.com/cortex-lab/Rigbox/tree/master/docs/setup)) and using certain Rigbox features (see also [`docs/usage`](https://github.com/cortex-lab/Rigbox/tree/master/docs/setup)) after an MC and SC installation. Furthermore, this page gives an overview of the repository's organization.
@@ -82,5 +105,4 @@ For further information, see [our publication](https://www.biorxiv.org/content/1
* [Psychophsics Toolbox](http://psychtoolbox.org) for code pertaining to visual stimulus presentation
* [NI-DAQmx](https://uk.mathworks.com/hardware-support/nidaqmx.html) for code pertaining to inerfacing with a NI-DAQ device
* [TooTallNate](https://github.com/TooTallNate/Java-WebSocket) for code pertaining to using Java Websockets
-* [Andrew Janke](https://github.com/apjanke) for the `isWindowsAdmin` function
-* [Timothy E. Holy](http://holylab.wustl.edu/) for the `distinguishable_colors` function
+* [Timothy E. Holy](http://holylab.wustl.edu/) for the `distinguishable_colors` function
\ No newline at end of file
diff --git a/addRigboxPaths.m b/addRigboxPaths.m
index 9825517f..c1689e1f 100644
--- a/addRigboxPaths.m
+++ b/addRigboxPaths.m
@@ -1,11 +1,10 @@
function addRigboxPaths(varargin)
%ADDRIGBOXPATHS Adds the required paths for using Rigbox
-% addRigboxPaths([savePaths, interactive, strict]) or
-% addRigboxPaths('SavePaths', true, 'Interactive', true, 'Strict', true)
+% addRigboxPaths([savePaths, strict]) or
+% addRigboxPaths('SavePaths', true, 'Strict', true)
%
% Inputs (Optional):
% savePaths (logical): If true, added paths are saved between sessions
-% interactive (logical): If true, user may be prompted for input
% strict (logical): Assert toolbox & system requirments are all met
%
% Part of the Rigging toolbox
@@ -17,7 +16,6 @@ function addRigboxPaths(varargin)
% Allow positional or Name-Value pairs
p = inputParser;
p.addOptional('savePaths', true)
-p.addOptional('interactive', true)
p.addOptional('strict', true)
p.parse(varargin{:});
p = p.Results;
@@ -47,8 +45,15 @@ function addRigboxPaths(varargin)
'Click here to install.'],...
'https://www.microsoft.com/en-us/download/details.aspx?id=48145')
+ % Microsoft Visual C++ Redistributable for Visual Studio 2013 must be
+ % installed, check for runtime dll file in system32 folder
+ assert(any(strcmpi('msvcr120.dll',{sys32.name})), 'Rigbox:setup:libraryRequired',...
+ ['Requires Microsoft Visual C++ Redistributable for Visual Studio 2013. ',...
+ 'Click here to install.'],...
+ 'https://www.microsoft.com/en-us/download/details.aspx?id=40784')
+
% Check MATLAB 2017b is running
- assert(~verLessThan('matlab', '9.3'), 'Requires MATLAB 2017b or later')
+ assert(~verLessThan('matlab', '9.5'), 'Requires MATLAB 2018b or later')
% Check essential toolboxes are installed (common to both master and
% stimulus computers)
@@ -74,7 +79,8 @@ function addRigboxPaths(varargin)
info = matlabshared.supportpkg.getInstalled;
if isempty(info) || ~any(contains({info.Name}, 'NI-DAQmx'))
warning('Rigbox:setup:toolboxRequired',...
- ['The stimulus computer requires the National Instruments support package to be installed. '...
+ ['To run full experiments, the stimulus computer requires '...
+ 'the National Instruments support package to be installed. '...
'Click here to install.'],...
'https://www.mathworks.com/hardware-support/nidaqmx.html')
end
@@ -133,7 +139,7 @@ function addRigboxPaths(varargin)
%%% Remind user to copy paths file %%%
if ~exist('+dat/paths','file')
- template_paths = fullfile(root, 'docs', 'setup', 'paths_template.m');
+ template_paths = fullfile(root, 'docs', 'scripts', 'paths_template.m');
new_loc = fullfile(root, '+dat', 'paths.m');
copied = copyfile(template_paths, new_loc);
% Check that the file was copied
@@ -157,42 +163,4 @@ function addRigboxPaths(varargin)
warning('Rigbox:setup:javaNotSetup',...
'Cannot use java classes without saving new classpath');
end
-
-%%% Attempt to move dll file for signals %%%
-MSVSC2013URL = 'https://www.microsoft.com/en-us/download/details.aspx?id=40784';
-fileName = fullfile(root, 'signals', 'msvcr120.dll');
-fileExists = any(strcmp('msvcr120.dll',{sys32.name}));
-copied = false;
-if isWindowsAdmin % If user has admin privileges, attempt to copy dll file
- if fileExists && p.interactive % If there's already a dll file there prompt use to make backup
- prompt = sprintf(['For signals to work propery, it is nessisary to copy ',...
- 'the file \n', strrep(fileName, '\', '\\\\'), ' to ',...
- 'C:\\\\Windows\\\\System32.\n',...
- 'You may want to make a backup of your existing dll file before continuing.\n\n',...
- 'Alternatively this file is installed with ',...
- '',...
- 'Visual C++ Redistributable Packages for Visual Studio 2013\n\n',...
- 'Do you want to proceed with copying? Y/N [Y]: '], MSVSC2013URL);
- str = input(prompt,'s'); if isempty(str); str = 'y'; end
- if strcmpi(str, 'n'); return; end % Return without copying
- end
- copied = copyfile(fileName, 'C:\Windows\System32');
-end
-% Check that the file was copied
-if ~copied
- warning('Rigbox:setup:libraryRequired', ['Please copy the file ',...
- '%s to C:\\Windows\\System32 ',...
- '\nor install ',...
- 'Visual C++ Redistributable Packages for Visual Studio 2013'], ...
- fileName, MSVSC2013URL)
-end
-
-function out = isWindowsAdmin()
-%ISWINDOWSADMIN True if this user is in admin role.
-% 2011 Andrew Janke (https://github.com/apjanke)
-if ~NET.isNETSupported; out = false; return; end
-wi = System.Security.Principal.WindowsIdentity.GetCurrent();
-wp = System.Security.Principal.WindowsPrincipal(wi);
-out = wp.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator);
-end
end
\ No newline at end of file
diff --git a/docs/README.md b/docs/README.md
index 9133862d..6f9fcafa 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,4 +1,5 @@
-This `docs` folder contains information on setting up and using Rigbox, as well as information on the organization of the repository. After installation, we recommend viewing and following the instructions in the main index page for getting started with Rigbox. To view the main index page, open `docs/html/index.html` in a web browser. E.g. to do so within MATLAB, run:
+# Documentation:
+This 'docs' folder contains files that are useful for learning how to use and set up Rigbox. To view the docs in HTML open `docs/html/index.html` in the MATLAB browser or visit [cortex-lab.github.io/Rigbox](https://cortex-lab.github.io/Rigbox/):
```matlab
root = fileparts(which('addRigboxPaths'));
url = ['file:///', fullfile(root, 'docs', 'html', 'index.html')];
@@ -6,11 +7,18 @@ web(url)
```
## Contents:
+The docs directory contains three things:
-- `setup/` - information on how to set up Rigbox on a new rig after installation.
-- `usage/` - information on how to use certain Rigbox features after setup.
-- `html/` - .html files that correspond to the .m files in `setup/` and `usage/`
-- `maintainers/` - files for maintainers which specify design and style choices and how to standardize maintenance and development of Rigbox.
-- `index.m` - Rigbox's documentation index page as a .m file. Corresponds to the `html/index.html` file.
-- `Rigbox UML.pdf` - a UML diagram of Rigbox.
-- `Troubleshooting_and_FAQ.m` - information on troubleshooting errors which arise in Rigbox, and frequently asked questions.
\ No newline at end of file
+- `scripts/` - The scripts used to generate the html files. These are useful if you wish to run some of the code in the docs, particularly `hardware_config.m`.
+- `html/` - The html docs and source images.
+- 'maintainers/' - Guidelines for code maintainers.
+- `Rigbox UML.pdf` - A UML diagram of the Rigbox class structure.
+
+
+## Contributing
+If you wish to make changes to the documentation, please follow the below steps:
+1. Make your changes to the documentation scripts on the `documentation` branch.
+2. Export all changed files to html using MATLAB's 'Publish' feature. Code execution can be disabled in the Publish Options.
+3. Copy the files from `docs/scripts/html` to `docs/html`.
+4. Run the `fixFiles` script to perform any post processing on the html files.
+5. Once committed to the `documentation` branch, merge this branch onto the `gh-pages` branch and copy the files from `docs/scripts/html` to the repository's root directory. Commit these changes to the `gh-pages` branch. They will now show up on the documentation Website.
diff --git a/docs/Troubleshooting_and_FAQ.m b/docs/Troubleshooting_and_FAQ.m
deleted file mode 100644
index f2fd33ea..00000000
--- a/docs/Troubleshooting_and_FAQ.m
+++ /dev/null
@@ -1,378 +0,0 @@
-%% Troubleshooting
-% Often finding the source of a problem seems daunghting when faced with a
-% huge Rigbox error stack. Below are some tips on how to quickly get to
-% the root of the issue and hopefully solve it.
-
-
-%%% Update the code
-% Check what version of the code you're using and that you're up-to-date:
-git.runCmd('status'); % Tells me what branch I'm on
-git.update(0); % Update now
-
-% If you're on a development or feature branch try moving to the master
-% branch, which should be most stable.
-git.runCmd('checkout master'); git.update(0);
-
-
-%%% Examining the stack
-% Don't be frightened by a wall of red text! Simply start from the top and
-% work out what the errors might mean and what part of code they came from.
-% The error at the top is the one that ultimately caused the crash. Try to
-% determine if this is a MATLAB builtin function, e.g.
-%
-% Warning: Error occurred while executing the listener callback for event UpdatePanel defined for class eui.SignalsTest:
-% Error using griddedInterpolant
-% Interpolation requires at least two sample points in each dimension.
-%
-% Error in interp1 (line 151)
-% F = griddedInterpolant(X,V,method);
-%
-% TODO Add better example of builtin errors
-%
-% If you're debugging a signals experiment definition, check for the line
-% in your experiment where this particular builtin function was called. NB:
-% You can check whether it is specific to your experiment by running one of
-% the example experiment definitions such as advancedChoiceWorld.m, found
-% in signals/docs/examples. If this runs without error then you're problem
-% may be specific to your experiment. You should see the name of your
-% definition function and exp.SignalsExp in the stack if they are involved.
-%
-% If you don't know what a function is, try checking the documentation.
-% Consider the following:
-%
-% Error using open
-% Invalid number of channels
-%
-% Error in audstream.fromSignal (line 16)
-% id = audstream.open(sampleRate, nChannels, devIdx);
-% [...]
-%
-% If you're unsure what `audstream.fromSignal` does, try typing `doc
-% audstream`. This should tell you that the package deals with audio
-% devices in signals. In this case the issue might be that your audio
-% settings are incorrect. Take a look at the audio section of
-% `docs\setup\hardware_config.m` and see if you can setup your audio
-% devices differently.
-
-
-%%% Paths
-% By far the most common issue in Rigbox relates to problems with the
-% MATLAB paths. Check the following:
-%
-% # Do you have a paths file in the +dat package?
-% Check the location by running `which dat.paths`. Check that a file is
-% on the paths and that it's the correct one.
-% # Check the paths set in this file.
-% Run `p = dat.paths` and inspect the output. Perhaps a path is set
-% incorrectly for one of the fields. Note that custom rig paths overwrite
-% those written in your paths file. More info found in
-% `using_dat_package` and `paths_template`.
-% # Do you have path conflicts?
-% Make sure MATLAB's set paths don't include other functions that have the
-% same name as Rigbox ones. Note that any functions in ~/Documents/MATLAB
-% take precedence over others. If you keep seeing the following warning
-% check that you've set the paths correctly:
-% Warning: Function system has the same name as a MATLAB builtin. We
-% suggest you rename the function to avoid a potential name conflict.
-% This warning can occur if the tests folder has been added to the paths
-% by mistake. Always set the paths by running `addRigboxPaths` and never
-% set them manually as some folders should not be visible to MATLAB.
-% # Check your working directory
-% MATLAB prioritizes functions found in your working directory over any
-% others in your path list so try to change into a 'safe' folder before
-% re-running your code:
-% pwd % display working directory
-% cd ~/Documents/MATLAB
-% # Check your variable names
-% Make sure your variable names don't shadow a function or package in
-% Rigbox, for instance if in an experiment definition you create a varible
-% called `vis`, you will no longer be able to access functions in the +vis
-% package from within the function:
-% vis = 23;
-% img = vis.image(t);
-% Error: Reference to non-existent field 'image'.
-
-
-%%% Reverting
-% If these errors only started occuring after updating the code,
-% particularly if you hadn't updated in a long time, try reverting to the
-% previous version of the code. This can help determine if the update
-% really was the culprit and will allow you to keep using the code on
-% outdated machines. Previous stable releases can be found on the Github
-% page under releases. NB: For the most recent stable code always pull
-% directly from the master branch
-
-
-%%% Posting an issue on Github
-% If you're completely stumped, open an issue on the Rigbox Github page (or
-% alyx-matlab if you think it's related to the Alyx database). When
-% creating an issue, read the bug report template carefully and be sure to
-% provide as much information as possible.
-%
-% If you tracked down the problem but found the error to be confusing or
-% too vague, feel free to post a feature request describing how better to
-% present the error. This is an area in need of improvment. You could also
-% make a change yourself and submit a pull request. For more info see
-% CONTRIBUTING.md
-
-
-%% FAQ
-% Below are some frequently asked questions and suggestions for fixing
-% them. Note there are plenty of other FAQs in the various setup scripts
-% with more specific information.
-
-
-%% Error and warning IDs
-% Below is a list of Rigbox error & warning IDs. This list is currently
-% incomplete and there aren't yet very standard. Typically the ID has the
-% following structure: module:package:function:error
-%
-% These are here for search convenience and may soon contain more detailed
-% troubleshooting information.
-
-% ..:..:..:copyPaths
-% Problem:
-% In order to load various essential configuration files, and to load and
-% save experimental data, user specific paths must be retrieved via calls
-% to |dat.paths|. This error means the function is not on MATLAB's search
-% path.
-%
-% Solution:
-% Add your +dat\paths.m file to MATLAB's search path. A template is
-% present in \docs\setup\paths_template.m. This file is automatically
-% copied by addRigboxPaths to +dat\. If you haven't already done so, run
-% |addRigboxPaths| to ensure all other paths have been correctly set.
-%
-% See also README.md for further setup information.
-%
-% IDs
-% Rigbox:git:update:copyPaths
-% signals:test:copyPaths
-
-% ..:..:noRemoteFile
-% Problem:
-% % TODO Add problem & solution for noRemoteFile error
-%
-% Solution:
-%
-%
-% IDs
-% Rigbox:mc:noRemoteFile
-
-% ..:..:..:notInTest
-% Problem:
-% This occurs when a mock function is called when the INTEST global
-% variable is not set. These mock functions shadow Rigbox and builtin
-% functions, meaning they have the same name.
-%
-% Solution:
-% If this function was called during a test, add the following to the top
-% of your test or in the constructor:
-% global INTEST
-% INTEST = true
-% Ensure that this is cleared during the teardown:
-% addteardown(@clear, INTEST) % If in a class
-% mess = onCleanup(@clear, INTEST) % If in a function
-%
-% If the mock in question is a class, set the InTest flag instead of the
-% global variable:
-% mock = MockDialog; % An example using MockDialog class
-% mock.InTest = true;
-% addteardown(@clear, MockDialog) % Clear mock class when done
-% mess = onCleanup(@clear, MockDialog) % If in a function
-%
-% If you are in not running tests, ensure that tests/fixtures is not in
-% your MATLAB path and that you are in a different working directory. It
-% is best to remove all Rigbox paths and readd them using `addRigboxPaths`
-%
-% IDs
-% Rigbox:tests:system:notInTest
-% Rigbox:tests:modDate:notInTest
-% Rigbox:tests:paths:notInTest
-% Rigbox:tests:pnet:notInTest
-% Rigbox:tests:modDate:missingTestFlag % TODO change name
-% Rigbox:MockDialog:newCall:InTestFalse
-
-% ..:..:..:behaviourNotSet
-% Problem:
-% A mock function was called while in a test, however the behaviour for
-% this particular input has not been defined.
-%
-% Solution:
-% If not testing a specific behavior for this function's output, simply
-% supress the warning in your test, remembering to restore the warning
-% state:
-% origState = warning;
-% addteardown(@warning, origState) % If in a class
-% mess = onCleanup(@warning, origState) % If in a function
-% warning('Rigbox:MockDialog:newCall:behaviourNotSet', 'off')
-%
-% If you're specifically testing the behavior when the mock returns a
-% particular output then check that you've set the input-output map
-% correctly: usually this is done by first calling the mock with input
-% identical to function under test as well as the output you want to see.
-% Check the input is formatted correctly. For more information see the
-% help of the particular mock you are using.
-%
-% IDs
-% Rigbox:tests:system:valueNotSet % TODO change name
-% Rigbox:MockDialog:newCall:behaviourNotSet
-%
-
-% ..:..:mkdirFailed
-% Problem:
-% MATLAB was unable to create a new folder on the system.
-%
-% Solution:
-% In general Rigbox code only creates new folders when a new experiment is
-% created. The folders are usually created in the localRepository and
-% mainRepository locations that are set in your paths file. If either of
-% these are remote (e.g. a server accessed via SMB) check that you can
-% navigate to the location in Windows' File Explorer (sometimes the access
-% credentials need setting first). If you can, next check the permissions
-% of these locations. If the folders are read-only, MATLAB will not be
-% able to create a new experiment folder there. Either change the
-% permissions or set a different path in |dat.paths|. One final thing to
-% check is that the folder names are valid: the presence of a folder that
-% is not correctly numbered in the subject's date folder may lead to an
-% invalid expRef. Withtin a date folder there should only be folders name
-% '1', '2', '3', etc.
-%
-% IDs
-% Alyx:newExp:mkdirFailed
-% Rigbox:dat:newExp:mkdirFailed
-%
-
-% ..:newExp:expFoldersAlreadyExist
-% Problem:
-% The folder structure for a newly generated experiment reference is
-% already in place.
-%
-% Experiment references are generated based on subject name, today's date
-% and the experiment number, which is found by looking at the folder
-% structure of the main repository. In a subject's experiment folder for
-% a given date there are numbered folders. When running a new experiment,
-% the code takes the folder name with the largest number and adds 1. It
-% then checks that this numbered folder doesn't exist in the other
-% repositories. If it does, an error is thrown so that no previous
-% experiment data is overwritten.
-%
-% Solution:
-% Check the folder structure for all your repositories (namely the
-% localRepository and mainRepository set in |dat.paths|). It may be that
-% there is an empty experiment folder in the localRepository but not the
-% mainRepository, in which case you can delete it. Alternatively, if you
-% find a full experiment folder in the local but not the main, copy it
-% over so that the two match. This will avoid a duplicate expRef being
-% created (remember, new expRefs are created based on the folder structure
-% of the mainRepository only).
-%
-% IDs
-% Alyx:newExp:expFoldersAlreadyExist
-% Rigbox:dat:newExp:expFoldersAlreadyExist
-%
-
-% ..:..:expRefNotFound
-% Problem:
-% The experiment reference string does not correspond to the folder
-% structure in your mainRepository path. Usually determined via a call to
-% |dat.expExists|.
-%
-% Solution:
-% Check that the mainRepository paths are the same on both the computer
-% that creates the experiment (e.g. MC) and the one that loads the
-% experiment (e.g. the one that runs |srv.expServer|). For an experiment
-% to exist, the subject > date > sequence folder structure should exist in
-% the mainRepository. To see the mainRepository location, run the
-% following:
-% getOr(dat.paths, 'mainRepository')
-% For example if the output is '\\server\Subjects\' then for the expRef
-% '2019-11-25_1_test' to exist, the following folder should exist:
-% \\server\Subjects\test\2019-11-25\1
-%
-% IDs
-% Rigbox:srv:expServer:expRefNotFound
-
-% ----- ! PTB - ERROR: SYNCHRONIZATION FAILURE ! ----
-% Problem:
-% To quote PsychToolbox: One or more internal checks indicate that
-% synchronization of Psychtoolbox to the vertical retrace (VBL) is not
-% working on your setup.This will seriously impair proper stimulus
-% presentation and stimulus presentation timing!
-%
-% Solution:
-% There are many, many reasons for this error. Here's a quick list of
-% things to try, in order:
-%
-% # Simply re-trying a couple of times. Sometimes it happens
-% sporadically.
-% # Check the monitor(s) are on and plugged in. If you're using
-% multiple monitors they should be of the same make and model. If they
-% aren't, try with just one monitor first.
-% # If you're using multiple screens in NVIDEA's 'Mosaic' mode, the
-% settings may have changed: sometimes Mosiac becomes deactivated and you
-% should set it up again.
-% # If you're using a remote connection for that computer it may be
-% interfering with the graphics settings. Examples of a remote
-% connection include VNC servers, TeamViewer and Windows Remote Desktop.
-% Try opening the PTB Window without any of these remote services.
-% # Update the graphics card drivers and firmware. This often helps.
-% # Read the PTB docs carefully and follow their suggestions. The docs
-% can be found at http://psychtoolbox.org/docs/SyncTrouble.
-% # If all else fails. You can skip these tests and check that there is
-% no taring manually. This is not recommended but can be done by setting
-% your stimWindow object's PtbSyncTests property to false:
-% stimWindow = getOr(hw.devices([],false), 'stimWindow');
-% stimWindow.PtbSyncTests = false;
-% hwPath = fullfile(getOr(dat.paths, 'rigConfig'), 'hardware.mat');
-% save(hwPath, 'stimWindow', '-append')
-
-%%% Undocumented IDs
-% Below is a list of all error and warning ids.
-
-% Rigbox:git:runCmd:nameValueArgs
-% Rigbox:git:runCmd:gitNotFound
-% Rigbox:git:update:valueError
-%
-% Rigbox:hw:calibrate:noscales
-% Rigbox:hw:calibrate:deadscale
-% Rigbox:hw:calibrate:partialPVpair
-%
-% Rigbox:srv:unexpectedUDPResponse
-% Rigbox:srv:unexpectedUDP
-% Rigbox:srv:expServer:noHardwareConfig
-%
-% Rigbox:dat:expPath:NotEnoughInputs
-% Rigbox:exp:SignalsExp:NoScreenConfig
-% Rigbox:exp:Parameters:wrongNumberOfColumns
-%
-% Rigbox:dat:expFilePath:NotEnoughInputs
-%
-% Rigbox:MockDialog:newCall:EmptySeq
-%
-% Rigbox:exp:SignalsExp:noTokenSet
-%
-% Rigbox:eui:choiceExpPanel:toolboxRequired
-% Rigbox:setup:toolboxRequired
-%
-% Alyx:newExp:subjectNotFound
-% Alyx:registerFile:InvalidPath
-% Alyx:registerFile:UnableToValidate
-% Alyx:registerFile:EmptyDNSField
-% Alyx:registerFile:InvalidRepoPath
-% Alyx:registerFile:InvalidFileType
-% Alyx:registerFile:InvalidFileName
-% Alyx:registerFile:NoValidPaths
-% Alyx:updateNarrative:UploadFailed
-%
-% Alyx:getFile:InvalidID
-% Alyx:getExpRef:InvalidID
-% Alyx:getFile:InvalidType
-% Alyx:expFilePath:InvalidType
-% Alyx:url2Eid:InvalidURL
-%
-% toStr:isstruct:Unfinished
-%
-% squeak.hw
-% shape:error
-% window:error
diff --git a/docs/html/Burgess_hardware_setup.html b/docs/html/Burgess_hardware_setup.html
new file mode 100644
index 00000000..0fdb4c0a
--- /dev/null
+++ b/docs/html/Burgess_hardware_setup.html
@@ -0,0 +1 @@
+
Instructions for steering wheel setup: hardware
Version 1.0.0, 14 February 2020
Lauren E Wool*, Miles J Wells**, Hamish Forrest, and Matteo Carandini *l.wool@ucl.ac.uk, **miles.wells@ucl.ac.uk Cortical Processing Laboratory, University College London
This document gives instructions on how to build a basic version of the steering wheel setup to probe mouse behavior, introduced byBurgess et al. (Cell Reports, 2017). The goal is to make it easy for other laboratories, including those that make the International Brain Laboratory, to replicate the task and extend it in various directions. To this end, these instructions rely entirely on materials that can be bought off the shelf, or ordered online based on 3-D drawings.
In this steering wheel setup, we place a steering wheel under the front paws of a head-fixed mouse, and we couple the wheel’s rotation to the horizontal position of a visual stimulus on the screens. Turning the wheel left or right moves the stimulus left or right. The mouse is then trained to decide whether a stimulus appears on its left or its right. Using the wheel, the mouse indicates its choice by moving the stimulus to the center. A correct decision is rewarded with a drop of water and short intertrial interval, while an incorrect decision is penalized with a longer timeout and auditory noise.
We use this setup throughout our laboratory, and deploy it in training rigs and experimental rigs. Training rigs are used to train head-fixed mice on the steering-wheel task and acquire behavioral data. Experimental rigs have additional apparatus to collect electrophysiological and imaging data, measure eye movements and licking activity, provide optogenetic perturbations, and so on.
Up until recently, constructing these setups required a machine shop that could provide custom-made components. However, for the purposes of spreading this setup to other laboratories, we here describe a new version that does not require a machine shop: all components can be ordered online or 3D-printed.
NB: An improved frame design can be found on the IBL Website. The improved frame and its components (mouse holder, etc.) may still be used with Rigbox.
The behavioral rig. A basic behavioral setup with three iPad screens (with Fresnel lenses), a mouse holder (with steering wheel), a water-delivery system, a head-fixation assembly, and a photodiode.
The main components of the behavioral setup are a mouse holder with steering wheel encoder, a water-delivery system, and three iPad screens for stimulus presentation. These and other components are held together by a “frame”. A “stimulus computer” controls all this apparatus. Additionally, a “master computer” controls the stimulus computer.
A 3D view of the rig is available here, and a detailed list of the components can be found in this spreadsheet. Note that this list was assembled in the UK; though we have aimed to use international vendors, you may need to pick different ones depending on your location (please let us know if you encounter difficulties). Place the orders as soon as possible, as some items will take time to arrive. Also, start planning how you will 3D-print the mouse holder.
Configuring the “stimulus computer” is more involved, and so it helps to have it in place first. This way you can use it to test other components as they arrive. The “master computer” can be configured once you are ready to run software.
Master computer
The “master computer” controls the stimulus computer and manages the experimental session, and monitors the mouse with a camera. It runs Windows 10. The computer should be connected to the network, ideally through a high-speed connection (not WiFi). Instructions for installing and managing experimental software for this computer can be found in the document "Software instructions for steering wheel setup." If you are not using our software, you do not necessarily need this computer.
Stimulus computer
The “stimulus computer” controls stimulus display and water delivery, and acquires the mouse’s movements on the steering wheel and the output of a photodiode to synchronize stimulus output with other measurements. It runs Windows 10. The computer should be connected to the network, ideally through a high-speed connection (not WiFi). Instructions for installing and managing experimental software for this computer can be found in the document "Software instructions for steering wheel setup."
Installing the video card
The required video card is the NVIDIA NVS 510. This card drives four monitors: a main display monitor and the three iPad screens. This is a typical installation that would apply to any card for a Windows machine; if you are not familiar with the process, detailed instructions are below.
Ensure your main monitor is connected to the onboard graphics card
If you are removing a currently graphics card, open 'Device Manager' and check the 'Display adapters' drill-down menu for the current graphics card
Double-click the graphics device: under the 'Driver' tab, select 'Uninstall' to remove any drivers associated with the current card.
After powering down and unplugging the computer, open the case and install the NVIDIA NVS 510 in the PCI slot. If you are replacing an existing card, remove it and replace it with the NVS 510.
Power up the computer and open 'Device Manager' and check that the 'Display adapters' drill-down menu shows a new object: 'Microsoft Basic Display Adapter,' or similar
Via your browser, find and download, then install, an appropriate driver for your new card. As of October 2017, the current driver for NVIDIA NVS 510 is the Quadro Desktop/Notebook Driver Release 387, Version R387 U1 (387.95).
Back in Device Manager, check that 'Microsoft Basic Display Adapter' has changed to the name of your GPU ('NVIDIA NVS 510').
Restart the computer for changes to take effect
Migrate the main display monitor to an NVS graphics card port using a suitable mini-DisplayPort cable, and confirm that you have visual output
Installing the DAQ device
To acquire data from the steering wheel and from the photodiode and to deliver water rewards to the mouse, we use a DAQ (data acquisition) device, the NI-DAQ 6211.
Plug in the device to a powered USB port on the stimulus computer
Visit the Drivers page on the National Instruments website and select ‘NI DAQmx’ from the ‘Popular Drivers and Updates’ list, then download the latest version of the device driver (17.1.1, as of October 2017).
Once installation is complete, restart the computer.
Launch ‘NI Device Monitor’ from the System Tray. The program should recognize that the NI-DAQ 6211 is connected, and a green light on the DAQ should flash
Frame and components
The setup itself comprises three iPad screens installed on posts, a mouse holder with a steering wheel encoder and head-fixation assembly, and a water-delivery system. Here we describe the assembly of the frame required to hold these and other components together.
Rig footprint diagram. The steering-wheel setup is contained entirely within a frame made of Thorlabs components, all seated on a 300mm x 300mm aluminium breadboard (MB3030/M). Components can be secured to the breadboard using 16mm M6 cap screws. The screen/Fresnel assemblies are seated between two grooved screws on clamps (one bottom, one top) that are attached to 300mm posts. The mouse itself is seated on a 3D-printed holder (not shown) that attaches to a magnetic plate in the center of the frame. In order for the Fresnel lenses to collimate light properly, the mouse’s head position must be equidistant from the three screens (indicated by the yellow ‘x’). This requirement is fulfilled with proper attachment of the holder to the magnetic plate (described below).
Assembling the frame
The frame is composed chiefly of Thorlabs components.
Assemble the three screen post mounts, by attaching each post holder (PH50/M) to a mounting base (BA2T2/M), then attach them to the breadboard (MB3030/M) as shown in the footprint diagram
Insert and secure 1 TR300/M post into each of the mounts
Wrap the thread of six PCMV/M V-groove screws 2-3 times with a ~5mm-wide piece of thread-seal tape. (The tape enables fine positioning and better tightening)
For each of six PMTR/M clamp arms, screw 1 PCMV/M into the first M6 tap (i.e., closest to the clamp) until the groove is perpendicular to the clamp arm. Rotate just until the screw is tight, and try not to reverse as this ruins the grip
On each post, firmly secure 1 PMTR/M clamp directly above the PH50/M, with the PCMV/M V-groove screw facing up. Each clamp arm should be perpendicular to its BA2T2/M plate and facing the center of the breadboard
On each post, attach 1 PMTR/M clamp ~20 cm above the lower clamp, facing the same direction, with the PCMV/M V-groove screw facing down. Tighten just to secure to the posts, as these will be readjusted
Preparing the screens
To protect the screens from damage, keep the plastic film on until you are ready to attach the Fresnel lenses
On a soft surface, turn the iPad over so that the back is facing up and the input cable is running along the top
Check that the cable input on the driver board has its locking mechanism (black plastic bar) pressed up
Carefully connect a driver board to the input cable. There will be ~1mm of gold contacts left visible. DO NOT FORCE THE CABLE.
Attach the driver to the back of the screen with some lab tape, ensuring the cable is not bending or shearing
Check that each driver board switch is set to 'OFF'
Attaching the Fresnel lenses
The purpose of the Fresnel lenses is to ensure that the intensity is homogeneous across the screen when viewed from a specific location (marked by a yellow ‘x’ in the rig footprint diagram above). To avoid pixel aliasing, the iPad screen and Fresnel lens must be separated by ~1 mm, using silicone pads. Various brands of window film may have different application instructions, so you may need to adapt steps 2–13 below.
Ensure the smooth side of each Fresnel lens is clean and dry, with no fingerprints (use an air duster if needed to remove debris)
Lay the lens on a bed of paper towels, smooth-side up with the short edge nearest
Cut a piece of window film that is slightly larger than the fresnel lens (~2 cm border)
Carefully peel back the adhesive and lay the window film next to the lens, adhesive-side up with the short edge nearest
Generously spray both the lens and the film with soap/water solution
Lift the window film from a short edge, letting it hang orthogonally to the surface of the fresnel lens
Slowly lower the film to the lens surface, allowing the bottommost short edges to begin contacting each other
Continue lowering to make contact with the lens, meanwhile using the squeegee to press out extra bubbles and solution to the sides
Continue working away from the bottom edge, lowering the film and using the squeegee to remove bubbles and solution
Lifting the lens/film, replace the wet paper towels with some new dry ones
Carefully flip the lens/film over so that the ridged side is now facing up
Trim the film edges with a razor or scalpel blade
Flip the lens over to remove any remaining bubbles with a squeegee, and further trim edges with a blade as needed. You may find there are white patches on the lens after applying the film. These will usually disappear after a few hours
Carefully remove the plastic protective film from the iPad screen and lay it face up
Cut four small pieces of silicone pad (~3mm x ~20mm) from the silicone rubber sheet, and apply them to each corner of the screen, atop the screen bezel, with the long dimension of the pad running along the long edges of the screen. The pads should not touch the screen display
Center the fresnel lens over the screen, with the rough side facing in, adjusting the silicone pads so that they lie between the screen bezel and the edge of the lens
Using four binder clips, clip the screen/Fresnel assembly together at each corner, centered over the pads (two clips on the top and two clips on the bottom). Ensure that the clips do not intrude on the viewable area of the screen, but only grip along the bezel where the pads are located.
Installing the screens
If you haven't already done so, ensure that the main monitor of the Stimulus computer is connected to the NVIDIA video card via a mini-DisplayPort cable, at port 4.
For each screen, center the bottom edge into the V-groove screw of the lower PMTR/M clamp. The output cable and driver board should be at the top of the screen on the back
While holding the screen assembly in place, lower the upper PMTR/M clamp down the post until its V-groove screw holds the top edge of the screen assembly, and then firmly secure its position with the thumbscrew
After each screen assembly has been attached to a post, make minor adjustments at each BA2T2/M plate to ensure that the screens are perpendicular to each other and that the edges of the fresnel lenses are flush
Once the screens are firmly in place and all connection points are secured tightly to the breadboard, plug in the AC power cable to each.
Connect each screen to the remaining NVS ports via the miniDP-to-DP display cables. Facing the screens, the leftmost screen should connect to port 1, the center to port 2, and the rightmost to port 3. The main monitor should connect to port 4.
Turn the driver board switches to 'ON'
Check that visual output appears onscreen. It is possible that the screens are out of order or the 'main display' option defaults away from your main monitor. This can be reconfigured, below.
Configuring the screens
The three iPad screens must be designated as a single viewable output, separate from the main monitor. This is accomplished using the NVIDIA Control Panel.
Launch the NVIDIA Control Panel
In the left panel, select ‘Select a task…’ > ‘Workstation’ > ‘Set up Mosaic’
Click ‘Create new configuration’
Under the ‘1. Select topology’ tab, select ‘Number of displays’ as 3 and choose a 1 x 3 topology with landscape orientation.
Check the box ‘I am using recommended connections for the selected topology’ and then click ‘Enable Mosaic’
Under the ‘2. Select displays’ tab, check the three iPad screens. These should be numbered 1 (0,0), 2 (0,1), and 3 (0,2). If they are not, rearrange the connections at the ports until this is satisfied.
Assign ‘Resolution per display’ to 1280 x 1024. If they are not already in the ‘Selected display sources’ box, drag them there and then click ‘Next’
Under the ‘3. Arrange displays’ tab, arrange the screen configuration so that 1-3 are arranged left to right. Apply the changes and select ‘yes’ to the dialog box prompting to save. Note: The main monitor will switch off and your working window will move to the 3-screen arrangement. Click ‘Finish’ ( skip overlap and bezel correction).
Return to the main control panel, this time choosing ‘Select a task…’ > ‘Displays’ > ‘Set up multiple displays’
Of the available displays, check the remaining box corresponding to the main monitor. In addition to the mosaic screens (labeled ‘3’), it will appear in the configuration window next to the 3-screen mosaic (display ‘3’) as display ‘4.’
Rearrange the screens in the preferred configuration, then right-click screen 4 and choose ‘make primary’. Apply and accept changes. The main monitor should now reactivate.
Launch Windows 10 > Settings > Display
For each of the displays, ensure that ‘Change the size of text, apps and other items’ is set to 100%
Assembling the mouse holder
The mouse holder comprises seating for the mouse, a steering wheel/encoder assembly, an articulated arm for delivering water rewards, and a head-fixation assembly.
The mouse holder assembly. Left: The mouse holder, seen from the front, shows the center bore that will accommodate the wheel assembly, as well as key attachment points to the KBM1/M breadboard. Center: The front of the holder shows the attachment point for the Fisso arm. Right: The back of holder shows the attachment point for the head-fixation assembly.
3D-print the (a) mouse holder, (b) mouse cover, and (c) wheel coupler designs. This can be done in-house or can be outsourced to third parties. Use PLA plastic for best results. If desired, the mouse cover can be printed in clear PLA so as to better observe mouse body movements
Connect the wheel coupler to the shaft of the rotary encoder. It should attach securely with a just strong push
Feed the rotary encoder through the large center bore on the front plate of the mouse holder, so that the coupler is facing outward and the encoder body is housed on the underside of the mouse holder. The encoder cable should be oriented downward
Feed three 5-mm M3 cap screws through the small bores on the front plate of the mouse holder, and then screw them into the threaded holes on the face of the encoder
To the top plate of the two-piece KBM1/M kinematic breadboard, attach the larger Fisso articulated arm to the front center hole (row 1, hole 3) of the KBM1/M, and secure tightly with an adjustable wrench
Connect the 3D-printed mouse holder to the KBM1/M top plate using four 45-mm M6 cap screws, as shown in the diagram above. The two front screws will be in row 1 (holes 1 and 7) and the two back screws will be in row 3 (holes 1 and 7). Ensure that the magnetic hex switch is oriented to one side for accessibility
Once the mouse holder is in position, assemble the LEGO wheel and hub, then gently secure it to the front cross of the coupler. There should be 1-2 mm of space between the wheel and the front face of the mouse holder
Rotate the KBM1/M hex screw to release the bottom plate from the mouse holder assembly
With a 20-mm M6 set screw, attach the TR200/M post to the KBM1/M top plate at row 6, hole 7
Attach the RA90/M right-angle clamp 2 mm below the top of the TR200/M post, with the second post bore pointed toward the back of the KBM1/M top plate.
Attach the RA180/M end clamp to the base of the TR50/M post, then feed the assembly through the open bore of the RA90/M, so that the RA180/M is centered over the mouse holder and the RA180/M bore is parallel to the KBM1/M top plate. Secure the RA90/M thumb screw
Attach the headplate holder to the base of the TR100/M post with a 16-mm M6 cap screw
Feed the holder/post assembly through the bore of the RA180/M until the headplate holder screw points are centered over the steering wheel. Secure the RA180/M thumb screw
Insert the two M3 thumb screws top-down into the headplate holder. These are to secure the animal’s headplate
Screw the KBM1/M bottom plate to the MB3030/M breadboard at the positions shown on the footprint diagram, then attach the holder assembly to the plate via the magnetic switch. (To avoid damage or injury, always make sure the magnetic switch is OFF before attempting to add or remove the top plate.)
Cut a 65mm x 35mm rectangle of silicone rubber sheeting, and use it to line the bore where the mouse will be seated. This adds a bit of padding for comfort, and can be washed with soap & warm water between sessions.
Adding the camera and speaker
A camera is essential for monitoring the mouse’s behavior during the task, and a speaker is necessary to transmit simple task-related sounds, like beeps and white noise.
Place the camera atop the left corner of the screens, where the left and center screens meet. If needed, use small pieces of poster putty to keep it stable. This needs to be positioned to view the front of the mouse holder at the top of the wheel, where the mouse’s face will be located during the task
Plug the camera into the Master computer
The camera can be managed with freeware (such as WebcamViewer, ManyCam, or the software that comes with the camera), which should be installed on the Master computer. This runs independently of any experimental software.
Plug the USB speaker into the Stimulus computer, and place the speaker on one corner of the MB3030/M breadboard, facing the mouse holder
Assembling the water-reward system
Making a spout guide. Use a length of 16AWG copper wire to extend the reach of the Fisso arm and enable water delivery to the mouse.
To make a spout guide, first cut an 8-cm length of copper wire. Using long-nose pliers, wrap the end into a 2-mm-diameter loop, then bend it to a right angle
Wrap the other end of the wire around the free M6 screw shaft of the Fisso arm, and secure with an M6 hex nut
Bend the spout guide so that it extends the length of the Fisso arm toward the top of the steering wheel
Position the water valve on one corner of the MB3030/M breadboard.
On each end of the tubing already in the pinch valve, connect the larger end of a 3/32" x 1/16 barbed reducing connector
Cut 50 cm of 1/32" ID x 3/32" OD tubing, and attach one end to one of the barbed connectors
Feed the tubing along the back of the Fisso arm and through the 2-mm loop, and adjust the tubing so ~5 mm extends. Gently secure the tubing to the Fisso with a piece of laboratory tape
Adjust the Fisso arm and spout guide so that the tube tip is centered in the bore of the mouse holder. Make sure the Fisso does not obstruct free movement of the wheel
Additional 1/32" ID x 3/32" OD tubing will connect to the other barbed connector. This length should be cut in order to reach a nearby water reservoir (use a graduated cylinder or other vessel with milliliter precision)
Connecting the water-reward system
Before troubleshooting, always power off the valve system by unplugging the power supply directly.
Cut two lengths each of red and black hookup wire. One red/black pair will connect the power supply and the other the DAQ board, so cut the lengths accordingly.
Strip 5mm of insulation from both ends of each wire
Connect the DC cable mount to the red/black wire pair that will supply power. Insert the red wire into the ‘+’ terminal and the black wire into the ‘–’ terminal. Secure the wires in the terminals by using a screwdriver to tighten the set screws. Ensure that no exposed wire is outside the mount housing.
Insert the CoolDrive valve controller driver into the prototyping mini-breadboard, so that its pins span multiple rows, not columns (i.e., the driver should run parallel to the center dividing well on the breadboard). The orientation of the driver is reversible, and pin information is twinned at each end (i.e., position 1 = position 9; position 2 = position 8, etc.). However, there is a LED trigger indicator on the driver, so consider its visibility when installing.
Connect the red (+) and black (GND) power-supply wiresat position 1 and 2 on the breadboard, respectively.
Connect the two wires of the valve at position 3 and 5. Note that these leads are interchangeable.
Connect the red (+) and black (GND) DAQ wires at positions 4 and 8, respectively.
Using a piece of electrical tape, tape over all the breadboard connections to avoid short-circuiting or injury.
On the back of the power-supply plug, adjust the voltage of the power supply to the 12V by rotating the switch position with a flathead screwdriver
Connect the 5.5mm DC (male) plug to the two-pin output of the power-supply lead. Ensure the correct polarity by matching up the ‘+’ symbols between the plug and the lead
Connect the red DAQ (+) wire at position 4 to the NI DAQ 6211 at port ‘AO0.’ Insert the wire into the port, and using a 2-mm flathead screwdriver, tighten the port’s set screw until the wire is secure
Connect the black DAQ (GND) wire at position 8 to the NI DAQ 6211 at port ‘AOGND.’ Insert the wire into the port, and using a 2-mm flathead screwdriver, tighten the port’s set screw until the wire is secure
Connect the male and female DC connectors for the power supply
Power the breadboard by plugging in the power supply to the wall socket
To test for valve function, launch ‘NI Device Monitor’ from the System Tray on the stimulus computer. The program should recognize the NI-6211, and a green light on the DAQ should flash
Select the ‘NI USB-6211:Dev1’ icon, and then select ‘Test this device’
In the Test Panels dialog box, migrate to the ‘Analog Output’ tab, then select ‘Mode: Voltage DC’
Alternate the ‘Output Value’ between (+) and (-) 5 V in the right pane, clicking the Update button each time.
The state of the valve (open or closed) will itself alternate with the alternating +/- 5V outputs—this will be evidenced by a small click and illumination of the green LED light on the driver board.
Connecting the rotary encoder
Isolate the gray, green, brown, and white wires in the cable output of the rotary encoder.
Connect the wires to the NI DAQ 6211 at positions PFI0 (gray), PFI1 (green), +5V (brown), GND (white) by inserting the exposed wire into the correct DAQ socket and securing it with a 2-mm flathead screwdriver until tight
Ensure the other, loose wires don’t short one another by trimming them or insulating each one with electrical tape
To test for encoder function, launch ‘NI Device Monitor’ from the System Tray.
Select the ‘NI USB-6211:Dev1’ icon, and then select ‘Test this device’
In the Test Panels dialog box, migrate to the ‘Counter I/O’ tab, then select ‘Mode: Edge Counting’ and ‘Pulse Terminal: /Dev1/PF10’
Click the Start button, then manually spin the wheel on the mouse holder. If the encoder is working properly, the counter value will increase quickly, irrespective of wheel direction.
Connecting the photodiode
A photodiode is critical for gamma-correcting the luminance output of the screens, and is important for measuring stimulus timing. However, it is not required for starting basic behavioral training and can be added at a later stage.
Attach the photodiode horizontally to the TR50/M post via the M4 screw
Insert the TR300/M post into the PH50E/M post holder
Place the PH50E/M on the breadboard so that the TR300/M post is near the rightmost edge of the right screen
Mount the PH50E/M to the breadboard using a CF125 clamping fork and M6 cap screw
Use the RA90/M right-angle clamp to connect the TR50/M and TR300/M post so that the photodiode lens is facing the screen
Adjust the clamp and post positions so that the photodiode lens is flush with the iPad screen and as far into the top righthand corner of the screen as possible
Connect the photodiode’s power supply and a male-male BNC coaxial cable to the photodiode output port.
Connect the open end of the coaxial cable to the female BNC socket with test leads
Strip 5mm of insulation from both ends of each wire
Connect the red BNC (+) wire to the NI DAQ 6211 at port ‘AI1.’ Insert the wire into the port, and using a 2-mm flathead screwdriver, tighten the port’s set screw until the wire is secure
Connect the black BNC (GND) wire to the NI DAQ 6211 at port ‘AI9.’ Insert the wire into the port, and using a 2-mm flathead screwdriver, tighten the port’s set screw until the wire is secure
Power on the photodiode (there are switches at both the photodiode housing and power supply)
To test for photodiode function, launch ‘NI Device Monitor’ from the System Tray on the stimulus computer. The program should recognize the NI-6211, and a green light on the DAQ should flash
Select the ‘NI USB-6211:Dev1’ icon, and then select ‘Test this device’
In the Test Panels dialog box, migrate to the ‘Analog Input’ tab, then select Channel Name: Dev1/ai1,’ ‘Mode: On Demand,’ and ‘Input Configuration: Differential’
Click the ‘Start’ button.
Free the photodiode slightly from its position near the screen so the sensor is visible. Without touching the sensor, carefully use your hand or a piece of cardstock to perturb the amount of light reaching it. This will cause the voltage reading to fluctuate, which will be visible on the onscreen graph.
Comments and suggestions
Now that you have your behavioral setup, you will want to place it in a sound insulation box or other quiet place to train your mice, or somewhere else in your lab, where you can acquire physiological data.
In following these instructions, you certainly will find that parts of this document can be improved. By all means, please make those improvement, by using the “suggest” feature if you are reading this in Google Docs, or by sending an email to Lauren or Miles.
An example of a steering-wheel setup used in a 2-photon imaging rig
Appendix: Components list
Category
QTY
Product
Specifications
Supplier
Notes
Stimulus computer
1
Computer
Processor: Intel Core i3 7100, 3.9 GHz
Memory: 16 GB (2 x 8 GB) Corsair 2133MHz DDR4 RAM, 1.2 V
Storage: 1TB WD Blue WD10EZEX, 7200rpm, 64MB Cache
OS: Windows 10 64-bit
Scan V10i
This computer controls the rig. For more details, see the document: "Software Instructions for Steering Wheel Setup". Note: When building multiple rigs, EACH rig needs its own Stimulus Computer, but these can all be controlled by one Master Computer
1
Graphics card
NVIDIA NVS 510
Insight Cat# VCNVS510VGA-PB
1
Keyboard & mouse
1
Monitor
1
mini-DP display cable
Connects the monitor to the video card
1
USB stereo speaker
Adafruit 3369
Master computer
1
Computer
Processor: Intel Core i3 4170, 3.70 GHz
Memory: 4 GB (2 x 2 GB) DDR3/DDR3L
OS: Windows 10 64-bit
Graphics Card: On-board graphics support
HP ProDesk 400 G2.5 (or similar)
This computer controls the Stimulus Computer. For more details, see the document: "Software Instructions for Steering Wheel Setup". Note: When building multiple rigs, EACH rig needs its own Stimulus Computer, but can all be controlled by one Master Computer. If you are not using our software, you do not necessarily need this machine.
Confirm the linked specifications, as part numbers can be inconsistent
1
Tubing
1/32" ID x 3/32" OD, 50 ft
Cole Parmer WZ-95702-00
2
Tube connector
Barbed Reducing Connector 3/32" x 1/16"
Cole Parmer WZ-41518-22
1
Power supply
1.5–12 V DC, 1A linear power supply
RS 615-8919
1
Mini breadboard
Pimoroni COM0101
1
Cable mount
2.1 x 5.5 mm DC (female), 2-pin
RS 810-4605
1
Roll red hookup wire
300V 22AWG, solid core
Alpha Wire 3051/1 RD005
1
Roll black hookup wire
300V 22AWG, solid core
Alpha Wire 3051/1 BK005
Rig frame
1
Breadboard
Thorlabs MB3030/M
3
Post
Thorlabs TR300/M
3
Post holder
Thorlabs PH50/M
3
Adjustable mounting base
Thorlabs BA2T2/M
6
Component clamp
Thorlabs PMTR/M
6
V-groove base adapter
Thorlabs PCMV/M
1
USB camera
Logitech C270
1
USB stereo speaker
Adafruit 3369
12
16mm M6 cap screw
RS 281-114 (or part of HW-KIT2/M)
RS 281-114 is a pack of 50, but only 12 screws total are required
Photo-
diode
1
Post
Thorlabs TR300/M
1
Post
Thorlabs TR50/M
1
Right-angle clamp
Thorlabs RA90/M
1
Post holder
Thorlabs PH50E/M
1
Clamping fork
Thorlabs CF125
1
Photodiode
Thorlabs PDA100A-EC
1
Power supply
Thorlabs LDS1212
1
Coaxial cable
50 Ω, Male BNC to Male BNC, 1m
RS 284-3792
1
Coaxial socket with test leads
Female BNC
Pomona 4969
Tools
1
Scissors
1
Razor blade
1
Squeegee/straightedge
This is to remove bubbles during film application, and usually comes with the film
1
Roll of write-on lab tape
Cole Parmer WZ-06530-21
1
Spray bottle with ~10% soap solution
~9:1 water:soap. The solution should be lightly coloured
Any regular dish detergent (e.g., Dawn, Fairy)
Mix gently until the soap is dissolved but the solution is not frothy
1
Air Duster 200 mL
Office Depot, Staples, etc.
1
5mm hex key
Thorlabs BD-5M
Ensure this is long enough for the bores of the mouse holder
1
2mm flathead screwdriver
1
Wire stripper/cutter
1
Long-nose pliers
1
Adjustable wrench
1
Roll electrical tape
1
Roll PTFE thread seal tape
12mm wide x 0.075mm thick (or similar)
RS 512-238
1
Pack poster putty
Bostik 'blu tack', Elmer's 'poster tack', etc.
Page
\ No newline at end of file
diff --git a/docs/html/Fig7_timeline.png b/docs/html/Fig7_timeline.png
new file mode 100644
index 00000000..4f184685
Binary files /dev/null and b/docs/html/Fig7_timeline.png differ
diff --git a/docs/html/using_parameters.html b/docs/html/Parameters.html
similarity index 90%
rename from docs/html/using_parameters.html
rename to docs/html/Parameters.html
index 44e94646..e31e4ebf 100644
--- a/docs/html/using_parameters.html
+++ b/docs/html/Parameters.html
@@ -6,7 +6,7 @@
Introduction
Introduction
This document contains information on how experiment parameters work in Rigbox. How to create them, edit them and save them.
NB: Not all uncommented lines will run without error, particularly when a specific hardware configuration is required. Always read the preceeding text before running each line.
Parameters are structures that contain experiment and session specific variables that may be set via a GUI and stored for each session. Parameters are stored as structures saved MAT files and may also be saved as JSON. They typically end in '_parameters' and are saved when creating a new experiment using the dat.newExp function or Alyx/newExp method. You can generate and retrieve paths for experiment parameter files using the dat package:
expRef = dat.constructExpRef('fake', now, 1); % Example experiment reference
+
Parameters
This document contains information on how experiment parameters work in Rigbox. How to create them, edit them and save them.
NB: Not all uncommented lines will run without error, particularly when a specific hardware configuration is required. Always read the preceeding text before running each line.
Parameters are structures that contain experiment and session specific variables that may be set via a GUI and stored for each session. Parameters are stored as structures saved MAT files and may also be saved as JSON. They typically end in '_parameters' and are saved when creating a new experiment using the dat.newExp function or Alyx/newExp method. You can generate and retrieve paths for experiment parameter files using the dat package:
expRef = dat.constructExpRef('fake', now, 1); % Example experiment reference
paramPath = dat.expFilePath(expRef, 'parameters') % Generate path for saving% Parameters can be loaded using an experiment reference via DAT.EXPPARAMS:
paramStruct = dat.expParams(expRef); % Returns empty if params don't exist% More info on generating paths can be found in USING_DAT_PACKAGE:
-open(fullfile(getOr(dat.paths,'rigbox'), 'docs', 'using_dat_package.m'))
+root = getOr(dat.paths,'rigbox');
+open(fullfile(root, 'docs', 'scripts', 'using_dat_package.m'))
Parameter structures
In signals a set of parameters may be extracted using EXP.INFERPARAMETERS (see note 1).
defFunction should be either an experiment definition function handle, or if the function isn't on MATLAB's search path, a char of the full path to such a definition function.
defFunction = fullfile(getOr(dat.paths,'rigbox'), 'tests', ...'fixtures', 'expDefinitions', 'advancedChoiceWorld.m');
paramStruct = exp.inferParameters(defFunction);
@@ -193,10 +194,8 @@
% c.f. [~, ~, trialParams] = parameters.toConditionServer(false)% See section below for more details on randomizing.
The ParamEditor GUI
The easiest way to modify parameters is via the ParamEditor GUI, managed by the eui.ParamEditor class. A ParamEditor object is embedded into MC and can also be instantiated via the Experiment Panels.
To instantiate a standalone editor, call EUI.PARAMEDITOR with a Parameters object. Additionally a parent figure handle may be provided.
There are two panels that make up the editor. On the left are the global parameters and on the right is the trial conditions table, containing the conditional parameters.
PE = eui.ParamEditor(parameters)
-
-
-
Global panel
The global panel is pretty simple. Each parameter is represented by the parameter name (formatted as a title, see above section) and an input field. When a field is modified the title turns red. For numrical and string parameters, vectors may be added by inputting values separated by commas. For instance typing '1, 3, 5' (without quotes) would set the value of that parameter to [1; 3; 5]. For numrical parameters spaces alone will suffice, e.g. '1 3 5'.
To make a parameter conditional, right-clicking on the input field or title and select 'Make conditional'. The parameter will now appear in the conditions table to the right.
Conditions panel
Here each parameter is represented as a table column, and its conditions (i.e. the columns of the parameter) as table rows. The rows may be re-ordered by dragging the field name of the column you with to move.
New blank conditions (i.e. rows) can be added by clicking the 'New condition' button at the bottom of the table.
Individual cells can be selected and edited as expected. To select multiple cells, hold down the ctrl key while clicking. To select multiple conditions in a row, hold the shift key. Once you've selected a cell in at least one column, the other buttons become available:
'Delete condition' allows you to delete the table rows of the selected cells (i.e. the selected trial conditions).
'Globalise parameter' makes the columns of the selected cells global parameters, whereby they are moved to the left panel. The value in the last selected cell for that parameter is used as the new parameter value. This may also be done via the context menu.
'Set values' allows you can set multiple cells are once. One clicked a small dialog appears with am input field for each selected column. The number of selected cells for each column is shown in brackets. Entering a single value will set each cell to that value. Entering a semicolon-separated list will assign each cell one value going from top to bottom. For example by selecting three cells in a column and typing '4; 5; 6' (without quotes) the top most cell will take the value '4' and so forth.
This is particularly useful for more involved stimulus sets with many conditions.
By right-clicking anywhere in the condition table you get two extra options:
'Sort by selected column' will sort the columns by whichever column the selected cell is in. Currently only sorting by one column is supported.
'Randomise conditions' is a checkbox that sets the underlying hidden parameter of the same name. By default this is checked. When unchecked, the rows of the table are given an index, indicating the set order trial conditions.
Once your parameters have been modified via the GUI they can be saved by extracting the underlying parameter stuct and saving to a file:
Let's look at some ways you can set trial condition parameters for different sorts of experiments. In the below examples imagine you have a signals experiment definition with three conditional parameters, A, B and C (see note 6).
By default all conditions are presented in a random order n times, where n is defined by the numRepeats parameter. If numRepeats is made a global parameter, then all conditions are presented the same number of times.
% Example 1: An illustration of how the trial order may turn out when
+
Global panel
The global panel is pretty simple. Each parameter is represented by the parameter name (formatted as a title, see above section) and an input field. When a field is modified the title turns red. For numrical and string parameters, vectors may be added by inputting values separated by commas. For instance typing '1, 3, 5' (without quotes) would set the value of that parameter to [1; 3; 5]. For numrical parameters spaces alone will suffice, e.g. '1 3 5'.
To make a parameter conditional, right-clicking on the input field or title and select 'Make conditional'. The parameter will now appear in the conditions table to the right.
Conditions panel
Here each parameter is represented as a table column, and its conditions (i.e. the columns of the parameter) as table rows. The rows may be re-ordered by dragging the field name of the column you with to move.
New blank conditions (i.e. rows) can be added by clicking the 'New condition' button at the bottom of the table.
Individual cells can be selected and edited as expected. To select multiple cells, hold down the ctrl key while clicking. To select multiple conditions in a row, hold the shift key. Once you've selected a cell in at least one column, the other buttons become available:
'Delete condition' allows you to delete the table rows of the selected cells (i.e. the selected trial conditions).
'Globalise parameter' makes the columns of the selected cells global parameters, whereby they are moved to the left panel. The value in the last selected cell for that parameter is used as the new parameter value. This may also be done via the context menu.
'Set values' allows you can set multiple cells are once. One clicked a small dialog appears with am input field for each selected column. The number of selected cells for each column is shown in brackets. Entering a single value will set each cell to that value. Entering a semicolon-separated list will assign each cell one value going from top to bottom. For example by selecting three cells in a column and typing '4; 5; 6' (without quotes) the top most cell will take the value '4' and so forth.
This is particularly useful for more involved stimulus sets with many conditions.
By right-clicking anywhere in the condition table you get two extra options:
'Sort by selected column' will sort the columns by whichever column the selected cell is in. Currently only sorting by one column is supported.
'Randomise conditions' is a checkbox that sets the underlying hidden parameter of the same name. By default this is checked. When unchecked, the rows of the table are given an index, indicating the set order trial conditions.
Once your parameters have been modified via the GUI they can be saved by extracting the underlying parameter stuct and saving to a file:
Let's look at some ways you can set trial condition parameters for different sorts of experiments. In the below examples imagine you have a signals experiment definition with three conditional parameters, A, B and C (see note 6).
By default all conditions are presented in a random order n times, where n is defined by the numRepeats parameter. If numRepeats is made a global parameter, then all conditions are presented the same number of times.
% Example 1: An illustration of how the trial order may turn out when% 'randomiseConditions' is false and 'numRepeats' is a conditional parameter:% +---+---+---+-------------+
@@ -269,7 +268,7 @@
Global panel
The global panel is pretty simple. Each paramet
% 4 | 3 | 3 | 4 |% 5 | 3 | 3 | 4 |% +---+---+---+
-
Using Set values
For more involved stimulus sets, we can use Set Values to conveniently set the values of multiple cells at once. This is particularly useful for experiments with many conditions.
% Example 4: Say you want to present each condition twice in a row, and the
+
Using Set values
For more involved stimulus sets, we can use Set Values to conveniently set the values of multiple cells at once. This is particularly useful for experiments with many conditions.
% Example 4: Say you want to present each condition twice in a row, and the% entire set two times, e.g.%% # | A | B | C |
@@ -320,7 +319,7 @@
Global panel
The global panel is pretty simple. Each paramet
% 11 | 6 | 4 | 4 |% 12 | 6 | 1 | 4 |% +---+---+---+
-
Notes and warning suppressions
(1) To load default parameters for legacy experiments, there are simple functions that return these paramteters. NB: The below are no longer used as signals provides more flexbility in running experiments.
choiceParams = exp.choiceWorldParams; % For the original Burgess task
+
Notes and warning suppressions
(1) To load default parameters for legacy experiments, there are simple functions that return these paramteters. NB: The below are no longer used as signals provides more flexbility in running experiments.
choiceParams = exp.choiceWorldParams; % For the original Burgess task
diskParams = exp.discWorldParams; % For a similar orientation-based protocol
rangeParams = exp.rangeParams; % A Burgess task prototype experiment% Various visual field mapping experiment parameteres
@@ -404,14 +403,12 @@
Global panel
The global panel is pretty simple. Each paramet
% Author: Miles Wells%
-% v1.0.0
+% v1.1.1
-% INTERNAL:
-% ln209 ParamEditor.png%#ok<*NOPTS,*ASGLU,*NASGU>
Timeline manages the acquisition and generation of experimental timing data using a NI-DAQ. The main timing signal, 'chrono', is a digital square wave that flips each time a new chunk of data is available from the DAQ. A callback function to this flip event collects the DAQ timestamp of the scan where each flip occured. The difference between this timestamp and the system time recorded when the flip command was given is recorded as the offset time and can be used to unify all timestamps across computers during an experiment. Thus, all event timestamps across all computers for a given experiment are recorded in times relative to the DAQ's clock. These timestamps can be interchanged with MATLAB and system times during an experiment. Timeline can acquire any number of hardware events and record their values with respect to this offset; for example, Timeline can use a photodiode to record the times at which the screen updates.
-
-
NB: Not all uncommented lines will run without error, particularly when a specific hardware configuration is required. Always read the preceeding text before running each line.
Timeline manages the acquisition and generation of experimental timing data using a NI-DAQ. The main timing signal, 'chrono', is a digital square wave that flips each time a new chunk of data is available from the DAQ. A callback function to this flip event collects the DAQ timestamp of the scan where each flip occured. The difference between this timestamp and the system time recorded when the flip command was given is recorded as the offset time and can be used to unify all timestamps across computers during an experiment. Thus, all event timestamps across all computers for a given experiment are recorded in times relative to the DAQ's clock. These timestamps can be interchanged with MATLAB and system times during an experiment. Timeline can acquire any number of hardware events and record their values with respect to this offset; for example, Timeline can use a photodiode to record the times at which the screen updates.
NB: Not all uncommented lines will run without error, particularly when a specific hardware configuration is required. Always read the preceeding text before running each line.
For more details on setting up Timeline, see hardware_config:
opentoline(fullfile(getOr(dat.paths,'rigbox'), ...'docs', 'setup', 'hardware_config.m'), 58)
-
-% NB: Not all uncommented lines will run without error, particularly when a
-% specific hardware configuration is required. Always read the preceeding
-% text before running each line.
-
-% Let's set up a timeline object:
+
NB : Not all uncommented lines will run without error, particularly when a specific hardware configuration is required. Always read the preceeding text before running each line.
% Let's set up a timeline object:
timeline = hw.Timeline;
-
-% To set up a new timeline object using setting from a previous experiment,
-% call the constructor with the variable saved in *_Timeline.mat for that
-% experiment:
-% ref = dat.constructExpRef('example', now - 10, 2); % Example experiment
-% hwPath = dat.expFilePath(ref, 'timeline', 'master');
-% timeline = hw.Timeline(loadVar(hwPath, 'hw')); % Load and instantiate
-
-% A JSON file is also saved after each experiment, currently with the name
-% TimelineHW.json:
-% hwPath = fullfile(dat.expPath(ref,'main','master'), 'TimelineHW.json');
-% timeline = hw.Timeline(jsondecode(fileread(hwPath)));
-
Inputs
The Inputs property contains a structure for configuring which channels to aquire data from.
timeline.Inputs
-
-% You can add a channel by adding directly to the Inputs property or by
-% using ADDINPUT:
-name = 'rotary encoder'; % Name of the device or signal you're acquiring
+
Using settings from a previous experiment
To set up a new timeline object using setting from a previous experiment, call the constructor with the variable saved in *_Timeline.mat for that experiment:
ref = dat.constructExpRef('example', now - 10, 2); % Example experiment
+hwPath = dat.expFilePath(ref, 'timeline', 'master'); % Path to timeline MAT
+timeline = hw.Timeline(loadVar(hwPath, 'hw')); % Load and instantiate
+
A JSON file is also saved after each experiment, currently with the name TimelineHW.json:
You can add a channel by adding directly to the Inputs property or by using addInput:
name = 'rotary encoder'; % Name of the device or signal you're acquiring
channel = 'ctr0'; % The channel the device is connected to
measurement = 'Position'; % The measurement type, i.e. 'volts', 'pos', 'edge'
timeline.addInput(name, channel, measurement)
-
-% Once an input is added you can view the wiring information with
-% WIRINGINFO:
-timeline.wiringInfo(name)
-
-% Extra parameters include terminal configuration (Differential or
-% SingleEnded, otherwise the channel default is used), axes scale, and a
-% flag indicating whether to use the input (true by default):
-timeline.addInput('lick detecter', 'ctr1', 'EdgeCount', [], 2, false)
-
-% The axes scale (set to 2 above) sets the plot scale when the Timeline
-% property LivePlot is set to true.
-timeline.LivePlot = 'on'; % Plot input data during acquisition
-
-% The UseInputs property contains a cellstring of the input names to be
-% acquired. This allows one to set up mutiple inputs that aren't
-% necessarily acquired every experiment.
-timeline.UseInputs % 'lick detecter' missing as we set the use arg to false
+
Extra parameters include terminal configuration (Differential or SingleEnded, otherwise the channel default is used), axes scale, and a flag indicating whether to use the input (true by default):
The axes scale (set to 2 above) sets the vertical plot scale when the Timeline property LivePlot is set to true (more on this later).
Activating Inputs
The 'UseInputs' property contains a cellstring of the input names to be acquired. This allows one to set up mutiple inputs that aren't necessarily acquired every experiment. The 'use' flag of addInput can set whether an input is added to UseInputs upon adding. The default is true.
timeline.UseInputs % 'lick detecter' missing as we set the use arg to false above% To activate an input again simply add it to UseInputs again:
timeline.UseInputs{end+1} = 'lick detecter';
-
-% Note that the order of channels in the UseInputs array determines the
-% order in which the channels are added to the DAQ session and thus the
-% order in which they are scanned during acquisition (see next section).
-
Dealing with ghosting
Multiplexing NI DAQ boards (as opposed simultaneously sampling boards) can be susceptible to 'ghosting', whereby weak differential channels (those with a small current source) are corrupted by neighbouring channels. A solution to this is to isolate the channel of interest by adding one dummy channel either side of it. This is a page on NI website explaining how to avoid ghosting: https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z0000019KzzSAE
For instance consider that we want to acquire the p.d. of a passive piezo:
Note that the order of channels in the UseInputs array determines the order in which the channels are added to the DAQ session and thus the order in which they are scanned during acquisition (see next section).
Dealing with ghosting
Multiplexing NI DAQ boards (as opposed simultaneously sampling boards) can be susceptible to 'ghosting', whereby weak differential channels (those with a small current source) are corrupted by neighbouring channels. A solution to this is to isolate the channel of interest by adding one dummy channel either side of it. This is a page on NI website explaining how to avoid ghosting: https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z0000019KzzSAE
For instance consider that we want to acquire the p.d. of a passive piezo:
timeline.addInput('piezoLickDetector', 'ai5', 'Volts', 'Differential',1,0)
% Now we can isolate this channel to prevent bleed-through by adding a% couple of 'dummy' channels that are scanned before and after our channel:
timeline.addInput('dummy1', 'ai4', 'Volts',[],1,0)
@@ -130,13 +99,12 @@
% Add them to UseInputs in the following order:
use = [timeline.UseInputs {'dummy1', 'piezoLickDetector', 'dummy2'}]
timeline.UseInputs = use;
-
-% NB: Channel names beginning with the word 'dummy' are not extracted as
-% ALF files. For more info see alyx-matlab:
-open(fullfile(getOr(dat.paths,'rigbox'), ...
+
NB : Channel names beginning with the word 'dummy' are not extracted as ALF files . For more info see alyx-matlab:
Timeline outputs are for setting up pulses for triggering external hadware acquisition devices. The main output class for timeline is HW.TLOUTPUT
doc hw.TLOutput
+
Wiring information
Once an input is added you can view the wiring information with the wiringInfo method:
name = 'rotary encoder';
+timeline.wiringInfo(name)
+
Connect rotary encoder to terminal ctr0 of the DAQ
Outputs
Timeline outputs are for setting up pulses for triggering external hadware acquisition devices. The main output class for timeline is hw.TLOutput
doc hw.TLOutput% An array of configured outputs are stored in the Outputs property of% timeline:
@@ -156,7 +124,7 @@
% The Verbose switch when 'on' will print extra information to the command% window during the experiment:
timeline.Outputs(1).Verbose = true;
-
Acquire Live
% Let's add another output:
+
Acquire Live
% Let's add another output:
timeline.Outputs(2) = hw.TLOutputAcqLive;
% The Acquire Live output by default outputs HIGH for the entire time an
@@ -180,7 +148,7 @@
% _ _% _| |__________...__________| |_% ^ start() ^ stop()
-
Output Clock
timeline.Outputs(end+1) = hw.TLOutputClock;
+
Output Clock
timeline.Outputs(end+1) = hw.TLOutputClock;
% The output clock object will produce a regular pulse troughout the% experiment, useful for triggaring frame acquisitions of a camera:
@@ -203,12 +171,13 @@
% For custom output signals that are not configurable with the current% TLOutput classes, simply create a new subclass with your desired% implementation.
-
Acquisitions
Timeline may be run automatically on the stimulus computer, or on a separate computer that's triggred by the stimulus computer via UDPs (for more info see using_services:
Timeline may be run automatically on the stimulus computer, or on a separate computer that's triggred by the stimulus computer via UDPs (for more info see using_services):
% Open the 'Using Services' script
+open(fullfile(getOr(dat.paths,'rigbox'), 'docs', 'using_services.m'))
% You can also start Timeline manually from the command prompt with% HW.TIMELINE/START. An experiment reference string is required:
ref = dat.newExp('default'); % Create an experiment for subject 'default'
-timeline.start(ref) % Start acquisition
+timeline.start(ref, Alyx('','')) % Start acquisition
timeline.IsRunning % true% In order to register Timeline file to the alyx database, an alyx object
@@ -241,7 +210,11 @@
% binary files during acquisition. This ensures that data aren't lost in% the even of MATLAB crashes.
timeline.WriteBufferToDisk = true; % Save data as they're collected
-
Clocks
doc hw.Clock
+
Live plotting
During acquisition you can plot the inputs live by setting the 'LivePlot' property to true / 'on'. The default plot figure position(1) can be set using the 'FigureScale' property. The values are in normalized units and is set as fullscreen by default. NB: This must be set before calling start.
timeline.LivePlot = 'on'; % Plot input data during acquisition
+timeline.FigureScale = [0 0 0.5 1]; % Take up half screen width and full height
+
The axes scale for individual inputs can be set be changing the 'axesScale' of the Inputs struct. This field controls the vertical scaling of each trace (multiplicative) and can be set when adding an input with the addInput method (see Inputs section). Below we change it manually:
doc hw.Clock% While timeline is running, timestampts can be returned using the TIME% method:
@@ -269,10 +242,15 @@
% reference time:
clock.zero()
clock.now()
-