Leader

Showing posts with label Additional functions. Show all posts
Showing posts with label Additional functions. Show all posts

Saturday, 13 August 2016

Generate sine wave/tone Matlab

Download
genTone.m


How-to
Generating tones or sine waves of specific frequencies in Matlab is conceptually simple, but generating the correct frequency over the correct time period at the correct sampling rate can be a bit confusing at first. This article deals mainly to generating sine wave tones, and genTone.m is designed to simplify this process, but the timing aspects also apply to any signal output from a digital system.


Monday, 31 August 2015

Matlab plot formats and how to quickly save high quality figures

Download
hgx.m
See also New graphics in Matlab 2014b and 2015 and creating nicer figures in one line of code for ng.m and og.m

The new graphics system in Matlab 2014b makes creating publication quality graphs much easier, but it still requires a little effort. See ng.m and og.m for two handy functions to improve the appearance of plots within Matlab. However, another important consideration is how to get the figure out of Matlab without ruining it. This function, hgx, is a handler for Matlab's various save/export functions and is designed to facilitate saving in useful forms using as little typing as possible


Saturday, 23 May 2015

Converting hexadecimal to binary

See also: Base conversion of positional number systems for other conversion functions.

Download
hex2bin2.m

Hexadecimal and binary
Hexidecimal and binary, like "normal" decimal are positional number systems, where individual digits have a value determined by their position in the sequence (see this post for a more detailed explanation). The difference between the three is that decimal has a base of 10 - it uses 10 numbers, 0-9, where hexadecimal has a base of 16 (using 0-9 and A, B, C, D, E and F) and binary has a base of 2 (using 0 and 1).

There are two ways to convert between hexadecimal and binary, mathematically, or by simply using a lookup table. Those interested in the mathematical process should check out the hex2dec2 and dec2bin2 functions (bin = dec2bin2(hex2dec2(hex))), which describe how to do each step. But if you'd just like to get it done and don't care about the maths behind it, just use hex2bin2. hex2bin2 uses the following lookup table to get the binary value of each hex digit.

Dec = Hex = Bin
 0   =   0   =   0000
 1   =   1   =   0001
 2   =   2   =   0010
 3   =   3   =   0011
 4   =   4   =   0100
 5   =   5   =   0101
 6   =   6   =   0110
 7   =   7   =   0111
 8   =   8   =   1000
 9   =   9   =   1001
10   =   A =   1010
11   =   B =   1011
12   =   C =   1100
13   =   D =   1101
14   =   E =   1110
15   =   F =   1111

Friday, 22 May 2015

Event / spike triggered average

Download
evTrigAvg.m

What caused an event?
Generally, event triggered averages are used to try and determine what caused an event to happen. They look at what preceded a number of events and take the average. In neuroscience events might be a spike recorded from a neuron in response to a certain stimulus. If the stimulus was white noise, for example, taking the time window from before the spike and averaging it would give the average stimulus that caused the neuron to fire. In finance the event could be a price change, and one might like to know if a consistent pattern occurs before similar price changes in order to react to them in the future.

evTrigAvg is designed to be general and agnostic to exactly what events and stimuli its dealing with are. All it needs is the "stimulus" and a logical vector of events (0s indicating no events, 1s indicating an event has occurred), and a window size to average over (in points).

Example
Let's generate some fake neural data as an example. Imagine an experiment where white noise is delivered to a subject and activity is recorded from a single neuron. The raw activity from the neuron will be noisy and will normally require preprocessing first, which will include filtering and event (spike) detection. Event detection is often done using a threshold of some value *the root mean square of the trace, where anything above this is marked as a spike. Or, if multiple units have been recorded, by much more complicated "spike sorting". I mention this mainly because it presents a fascinatingly complex problem, but it's not something we need to worry about here. The goal of preprocessing is to obtain a clean vector of events represented as 0s or 1s, we'll imagine the preprocessing has already been done, and we have this clean vector of events (spikes). We want to know what property of the stimulus caused each event.

nPoints = 10000;
stim = randn(1,nPoints);
resp = stim>2;
resp = [zeros(1,100), resp(1:end-100)];

nPoints determines the number of points in the stimulus (stim) and response (resp). stim is random noise drawn from a normal distribution. resp will be our vector of events (spikes), and for the sake of demonstration spikes are generated whenever the stim is greater than the entirely arbitrary value 2. Obviously, this means we know what stimulus property that is eliciting the spikes already, but pretend this is real data that we don't yet know anything about it. The line stim>2 returns a logical vector of 0s and 1s, which we'll also offset slightly relative to stim to emulate the latency that would exist in a real system (spikes aren't instant) by dumping 100 zeros at the start.

Let's plot out the first 1000 points of data we've just magically generated without having to do any pesky experiments.

subplot(2,1,1), plot(stim(1:1000))
line([1, 1000], [2, 2], 'LineStyle', '--', ...
    'color', 'k')
ylabel('Mag, arb'), title('Stimulus')
subplot(2,1,2), plot(resp(1:1000), 'r')
ylabel('Spikes'), title('Response')
xlabel('Time, pts')

Saturday, 2 May 2015

Fitting a better psychometric curve (Wichmann and Hill 2001)

Code
GitHub: Matlab code and Python package

Introduction
Psychometric curves quantify the relationship between stimulus parameters and an observer's subjective experience. For an introduction to the concept of psychometric curves in signal analysis theory and a function and instructions to fit a basic curve in Matlab, see Introduction to psychometric curves and fitting a simple psychometric function. This article will focus on fitting a more complex curve with additional parameters that allow for the subjects fallibility, which improves estimation of the key parameter, discrimination sensitivity.

The psychometric function used here is from the paper The psychometric function:I. Fitting, sampling, and goodness of fit, F. Wichmann and N. Hill 2001. This paper, and its companion paper, provide detailed theory and methods for fitting a psychometric function, assessing its goodness of fit, and finding confidence intervals for the ranges of the parameters estimated. This article will demonstrate how to fit Wichmann and Hill's psychometric function in Matlab using the same data from a fictional 2AFC experiment in this post. This will allow an interested reader to make a direct comparison between the Wichmann and Hill curve and the approach using Matlab's glmfit function with a built in binomial distribution and a logit link function.

Sunday, 19 April 2015

Introduction to psychometric curves and fitting a simple psychometric function

Code
GitHub: Matlab code and Python package

Introduction
An important aim of psychophysics is to quantify the relationship between stimulus parameters and an observer's subjective appreciation of what's going on. Signal detection theory approaches this problem by attributing perceptual sensitivity to thresholds that act at multiple levels in a system. In this context, a threshold could, for example, be how loud a sound needs to be to determine its location to a certain degree of accuracy, or how long a light needs to be on to determine its direction of movement. Above threshold, and the task is possible to a certain degree of accuracy. Below threshold and it's not possible to discriminate as accurately.

Experimentally, thresholds are often measured in two-alternative forced choice (2AFC) tasks or in go-no go paradigms (GNG). In 2AFC tasks a subject is asked to indicate one of two choices in response to a stimulus. For example, indicate white if a colour appears white, or black if it appears black in response to a shade of grey. Alternatively, GNG tasks require a subject to not respond ("no go") until a stimuli meets a certain criteria, then respond ("go").

In both of these types of task, a subjects performance can be measured as a function of the stimulus parameters - either as % correct, or similar, in 2AFC or d' in GNG, where d' is a function of hits, misses, and false alarms. Regardless of the exact metric used, the subjects performance can be described by two main parameters; bias (the "point of subject equality", PSE) and discrimination sensitivity (as in ability to discriminate between two conditions, such as white and black).

For example, imagine a subject performing a 2AFC task where they're presented with a shade of grey and they have to press one button to categorise the colour as white, or another button to categorise the colour as black. Intuitively, they're more likely to classify a grey stimulus as black the closer it is to black, and less likely the colour it is to white. So plotting their responses as a proportion of black responses (y) against the stimuli presented (x). We could use this sort of task to see how other factors, like the colour of a background, could affect perception of the shade of grey.



Sunday, 22 March 2015

New graphics in Matlab 2014b and 2015 and creating nicer figures in one line of code

Download
og.m
ng.m
see also Matlab plot formats and how to quickly save high quality figures for hgx, a function to handle exporting figures.

The new graphics system in Matlab 2014b has a few handy features, including:
  • Perceptually-equally spaced default colours (although be careful, red is near green)
  • OpenGL hardware rendering - smooth lines!
  • Easier access to handle properties using structure syntax - eg. handle.FontSize = 12, instead of set(handle, 'FontSize', 12). 
Even so, it still takes a little bit of effort to render nice figures and graph in Matlab, the default settings don't look great. Generally lines need to be made thicker, fonts bigger, etc., etc. Each setting requiring a line of code. Also, OpenGL can be a bit unreliable; it switches to software rendering on a whim, which disables features like anti-aliasing.


Saturday, 21 March 2015

Race model inequality script; R. Ulrich, J. Miller, H. Schröter, 2007

http://link.springer.com/article/10.3758/BF03193160#
Behavior Research Methods
May 2007, Volume 39, Issue 2, pp 291-302
Testing the race model inequality: An algorithm and computer programs
Rolf Ulrich, Jeff Miller, Hannes Schröter

In psychophysics the race model is used to compare reaction time data from two conditions (X,Y) to a third condition (Z). For example, response times to an auditory task and a visual task, compared to an audiovisual task. It tests if reaction times are faster in the third condition, and if so, they violate the race model and (possibly, depending on the task) represent multisensory integration. The race model inequality, simply, is defined as  P(RTz) < P(RTx) + P(RTy). For a better, and far more detailed explanation and run through - see the above paper!

In this paper, the authors present an algorithm to test the race model inequality and include a set of functions for Matlab that implements the algorithm, although no supplementary .m file appears to be included. The code is in the .pdf, but copying from a .pdf is, as usual, an unnecessarily painful experience.

Here is a slightly modified version of the code included in the paper, it's copied from the .pdf and corrected for various illegal characters, line breaks, etc. etc. Apart from a couple of minor edits, nothing else is changed from the authors original work.

Also included as an example of how to use RaceModel.m is a script (RaceModelTester.m) that generates some reaction time data in the correct form to use with RaceModel.m. The RT data supplied to RaceModel.m should be in three rows, rounded and in milliseconds. There should also be a vector of probabilities, and a true or false to indicate whether to create a plot or not.


AdSense