-
Notifications
You must be signed in to change notification settings - Fork 0
/
README
88 lines (67 loc) · 9.85 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# Specifying your analysis:
- Variables that change frequently are specified in buildAnalysisParamFile.m, or in additional files built off the buildAnalysisParamFile template. This has two positive effects. First, variables that change are in a separate file from the code, which makes versioning easier. Second, a copy of the processing parameters is always stored with the analyzed data.
- The structure of the stimulus space is described in a mat file, whose name is specified as the variable stimParamsFilename in buildAnalysisParamFile. The core of this file is the variable paramArray, a cell array with two indices, the first over stimuli (for example an image or a movie), the second over stimulus properties. The first property is take to be the unique identifier or the stimulus. Subsequent properties specify category membership: specifically, each category to which the stimulus belongs has its name in the stimulus’s cell. Categories can be listed in any order. They can overlap in any way. For instance, here’s paramArray for a tiny FOB type stimulus set:
{{‘humanFace1.bmp’,’face’,’humanFace’},{‘monkeyFace1.bmp’,’face’,’monkeyFace’},{‘body1.bmp’,’nonface’,’body’},{‘apple1.bmp’,’fruit’,’object’,’nonface’}}
Note that the order in which stimuli appear in paramArray sets the order in which they appear in the default psth by image.
Additional variables in the stimulus parameter file are:
- pictureLabels: the name (for display in figures, filenames, etc.) of each stimulus: a cell array of strings, with the same length and indexing as paramArray.
- categoryLabels: a list of names for categories. Like pictureLabels, it is a cell array of strings, but they can appear in any order. However, certain plotting functions will arrange categories in this order. For instance, this is the order that will be used to show a default psth by category.
- for an example of how to build this file using filenames that contain stimulus and category information, see buildStimParamFileFOB.m in the master branch.
- note: you should make sure there are no underscore characters in your pictureLabels and categoryLabels. Matlab interprets underscores as the start of a subscript block when printing titles, legends, etc. If you want an underscore, you can probably ‘escape’ the underscore using a single quote, but I haven’t tested that behavior. See https://stackoverflow.com/questions/15486611/how-to-add-before-all-special-characters-in-matlab
- important note: the names in pictureLabels and categoryLabels must be valid fieldnames for matlab structures. A to-be-written stimulusParamFileChecker will check for this; as of 5/11/18 using an invalid name will lead to uncaught fatal errors. See https://www.mathworks.com/matlabcentral/answers/343933-matlab-invalid-field-name
A target for future development is to make the variable names more intuitive for situations in which there isn’t a one-to-one map from stimulus files to alignment points, for example where alignment points are certain frames in a movie, behavioral events, or stimuli preceded by specific other stimuli. The current framework can accommodate all these situations: you just think of ‘pictureLabels’ as ‘alignmentPointLabels’, and the first entry in paramArray as the unique identifier of your alignment point type, which could be ‘movie1frame30’, or ‘im1afterim2,’ or ‘lipsmackOnset’, or even ‘11000101’ if you’re using serial digital IO packets as alignment points and, for simplicity, want to use their raw packet bits as the unique identifiers. It will be up to your preprocessLogFile code to figure out which times in the recording correspond to which alignment point, given these unique identifiers.
High-level Architecture:
- processRun is the top-level function to analyze one ephys run. To do this, it: —- calls buildAnalysisParamFile, then reads the variables file it writes.
—- calls preprocessSpikes, preprocessLog, preprocessLfp, preprocessAnalogIn to load data and deal with file-format specific aspects. If you want to use this library with systems other than Visiko/Blackrock, these four functions are what you’ll need to modify
—- calls excludeTrials to remove trials where e.g. fixation broke, fix spot flashed, etc.
—- reads the stimulus and category information in stimParamFilename, and parses trials by stimulus and category
—- calls alignSpikes and alignLFP to parse ephys data by stimulus and category structure
—- calls runAnalyses to run analyses, e.g. psth’s; preferred stimuli; data quality checks; category preferences; tuning curves; receptive fields; LFP and spike power and coupling spectra (time averaged and time-frequency); LFP and spike auto- and cross-correlograms; and more to be added later including Granger causality, partial coupling, and tuning transfer.
The preprocessing and alignment functions take their configuration variables from an input variable called params, which is a structure. The params structs are built in buildAnalysisParamFile. Each function’s docstrings describes the fields needed for its params struct, and any defaults values or optional fields.
Displaying text:
To display debugging and progress information, the code uses a library called Output. This library lets you specify one of three output ‘levels:’ DEBUG, VERBOSE, and INFO. This level is defined as a parameter in buildAnalysisParamFile, and set in processRun. A print statement has the form Output.DEBUG(string), Output.VERBOSE(string), or Output.INFO(string). In addition to letting you easily toggle the verbosity, this library has the excellent property that it gives the line and function from which each printed statement originated. That makes it annoying for displaying long blocks of text, like a list of preferred stimuli, so for such blocks I use disp(string).
Nomenclature:
- Run: one instance of data collection, from when you hit start on the data logger to when you hit end
- Possible future nomenclature
—- Site: one location for one electrode, or set of locations for multiple (not yet used)
—- Unit: to be improved, the recordings from one isolated cell
—- Penetration: all the recordings from a given penetration
Getting started to-do:
- make your stimulus params file
- make your buildAnalysisParamsFile based on the template
- make your preprocessLogFile, if you’re doing something other than a simple Visiko bcont task.
- run processRun
System requirements and dependencies:
- Matlab R2016a or later
- Signal Processing Toolbox (DPSS tapers, lfp filtering)
- Statistics and Machine Learning Toolbox (for bootstrap functions)
Optional, will accelerate:
- Parallel computing toolbox
- System Identification Toolbox
Some Matlab idiosyncrasies:
- given a structure s, the syntax s.(‘someString’) accesses the field someString of s, for either setting or getting. Matlab calls this using ‘dynamic field names.’ See https://www.mathworks.com/help/matlab/matlab_prog/generate-field-names-from-variables.html
- putting %#ok at the end of a line surpasses Matlab warnings about that line. Entertainingly, if you use this flag on a line where there are no warnings to supress, Matlab generates a warning that you suppressed a nonexistent warning!
Code sync to servers: use git, or
Initial sync:
from the server directory, >> rsync -rz yourMachineIP:/path/to/analysisCode .
Quick sync:
from the server directory, >> rsync -r —-exclude “*dependencies” —-exclude “*.git*” yourMachineIP:/path/to/analysisCode .
Guidelines for modification:
- We should discuss this together. A major goal of this project is to separate the parts of the code that everyone modifies from the parts that almost no one modifies. The structure doesn’t do that perfectly yet. In particular, it doesn’t separate plotting functions (which people might want to modify to suit their aesthetic idiosyncrasies) from compute steps, which should remain relatively static. More later…
- Using git:
—— view changes since last commit: >> git diff filename, or >> git diff —-cached filename, see https://stackoverflow.com/questions/4456532/how-can-i-see-what-has-changed-in-a-file-before-committing-to-git
—— merge: >> git merge otherBranchName
—— stage all files for commit: >> git add .
—— check which files have changed, and which are staged for commit: >> git status
—— commit your files: >> git commit -m ‘brief description of what you changed’
—— push your commits to github: >> git push
—— temporarily revert to past version: >> git stash, then >> git checkout hashOfOtherCommit (can get from git log, or from the link to the commit on github).
—— work on the tip of a branch (for instance, return to where you were before checking out a previous commit): >> git checkout nameOfOtherBranch
Style Guide:
- use two spaces as your indent. To do this, set tab size and indent size as described here: https://www.mathworks.com/help/matlab/matlab_env/about-editor-debugger-preferences.html
- use abbreviations sparingly in variable names; where not painfully obvious, say what the abbreviation is abbreviating in a comment when the variable first appears in each function
- variable and function names are of the form thisVariableName. This is even true for acronyms, so, for instance thisNameIncludesPsthSee. One exception is trailing acronyms, which may be all caps, e.g. preprocessLFP
- the on exception is loop iterators. In general, these should be of the form thingItsIterating_i, for example, channel_i for a loop over channels.
- don’t put multiple statements on one line
- do not display a variable by omitting a training semicolon. Display it using the Output library or, if that isn’t practical for a long block of text, the disp() function.
- Function docstrings should give the types of all input and output variables, and a brief description where the variable name leaves ambiguity. In particular, should describe the indexing scheme in input or output arrays.