This Repo provides MATLAB code for the basic GLM analyses in Yates et al. (2017)
Create a local copy of mtlipglm by cloning or downloading a zip
git clone https://github.com/jcbyts/mtlipglmYou will also need the classy branch of neuroGLM code
git clone https://github.com/jcbyts/neuroGLM
cd neuroGLM
git checkout classyAn example session can be found here
Note: this code has only been tested on MATLAB versions between 2015b and 2018a.
Open Matlab. Change directories to mtlipglm. You need to set up the specific paths for your machine.
edit addMTLIPpathsFind the lines
% this is where your data live
dataPath = '';and
% neuroGLM - must be downloaded from https://github.com/jcbyts/neuroGLM -- you want the classy branch for this to work properly
neuroGLMpath = '';and enter the appropriate path locations for the base data directory and the neuroGLM repository.
run addMTLIPpaths and if setup correctly, then
ls(getpref('mtlipglm', 'dataPath'))should show you the neurons, stim, main_fits, and lip_trunc_fits directories.
To begin exploring the data, the script cmdExamplePTA.m walks through the pulse-triggered average analyses from figure 2. The script works as a walkthrough and should be self-explanatory.
edit cmdExamplePTA.mTo explore the data / try alternate GLM parameterizations,
edit cmdExample.mThere are many parameters in the GLM and fitting usually requires some regularization. The GLMs here are regularized in two ways: The first is that the weights are parameterized on user-specified basis functions. The basis functions that are chosen specify the resolution of the fit and impose some smoothness. The second is that the weights on the basis functions are fit with ridge regression. This imposes shrinkage and biases the weights to be small. These hyperparameters can change the exact values of the weights and the resulting model fits by a non-trivial amount, however the fits are usually very robust to many settings of the basis functions and hyperparameters. To get a feel for how the basis and the ridge paramter changes the fitted models, explore the code in cmdExample. In the fits that are provided in the download link above, the basis functions were set to be identical for all units from each area. The ridge parameter was learned by searching over a grid on witheld data from the training set. The fitting code provided here fits the GLM with a fixed ridge parameter. The resulting fits will be subtly different than the ones provided in the link above.
There are a few classes that govern the analyses in mtlipglm.
Try running
dataPath = getpref('mtlipglm', 'dataPath');
neurons = getNeurons('p20140307', dataPath)You'll notice that neurons is an array of neuro objects. This is the most memory efficient way to access the neuron data. Each neuron file is an hdf5 file that includes many attributes about the unit under study (e.g., receptive field maps, waveform properties). Rather than load all of these files and atributes into memory, the neuro object can access each attribute when needed. To get the full struct for a neuron, just run
n = neurons(1).getStruct;or load the file directly. However, as mentioned, the code is going to use the neuro class, both because of its lazy access properties, but also because it has a number of useful methods for getting more info about the neuron. The neuro class has a property stim that similarly accesses the stimulus properties when needed.
The rest of the code revolves around two classes: mtlipglm and glmspike
glmspike is an inherits neuroGLM and can be used the same way. It contains additional methods for setting up particular parameterizations of the basis functions, compiling the design matrix, and performing the fitting.
mtlipglm is the workhorse. It creates a trial structure that is required by neuroGLM. It sets up the specific glmspike objects for each GLM and fits them. It also has model comparison code to analyze the data.