22
33For an example of how to modify Bpod trials extraction (with either Bpod only or unchanged DAQ time alignment) check out
44'projects.neuromodulators'. For an example of custom task QC, see 'projects.samuel_cuedBiasedChoiceWorld'.
5+
6+ ===========
7+ Definitions
8+ ===========
9+
10+ - **Bpod trials extractor**: A class for extracting trials data from the raw session data.
11+ This class saves trial and other session data to ALF dataset files. An extractor is associated to
12+ a session via the task protocol name to extractor class name map file in `projects/task_extractor_map.json`.
13+ - **Pipeline task**: A pipeline task is instantiated by the preprocessing pipeline and uses the
14+ Bpod trials extractor to extract the session datasets. It also performs DAQ time alignment, runs
15+ QC checks and registers/uploads the data. It can also optionally download the raw session data
16+ if re-running extractions from a remote location. A pipeline task is associated to a session via
17+ the session class :py:attr:`iblrig.base_tasks.BaseSession.extractor_tasks` attribute.
18+ - **Session**: The iblrig Session class that defines a behaviour task protocol (e.g. the Bpod state
19+ machine, task parameters, etc.)
20+ - **experiment description**: The file used by the pipeline to determine which protocol which run,
21+ its pipeline extractor classes, raw data locations, and also which DAQ should be used for time
22+ alignment. This file is generated automatically based on the iblrig hardware settings and session
23+ protocol.
524"""
625from collections import OrderedDict
726
@@ -15,6 +34,18 @@ class TemplateBpodTrialsExtractor(BaseBpodTrialsExtractor):
1534 """
1635 Extract ALF trials files for a custom Bpod protocol.
1736
37+ Bpod trials extractors should be a subclass of the
38+ :class:`ibllib.io.extractors.base.BaseBpodTrialsExtractor` class and should be for extracting
39+ Bpod trial events only. For separate DAQ time alignment, a second class should be used (see
40+ :class:`ibllib.io.extractors.ephys_fpga.FpgaTrials` and
41+ :class:`ibllib.io.extractors.mesoscope.TimelineTrials` for examples).
42+
43+ To associate this extractor to your task protocol, you must add it to the
44+ `projects/task_extractor_map.json` file. Additionally you can associate `Alyx procedures`_ (e.g.
45+ 'Optical stimulation') to the protocol with the `projects/task_type_procedures.json` file.
46+
47+ .. _Alyx procedures: https://openalyx.internationalbrainlab.org/admin/actions/proceduretype/
48+
1849 Attributes
1950 ----------
2051 bpod_trials : list of dict
@@ -24,7 +55,9 @@ class TemplateBpodTrialsExtractor(BaseBpodTrialsExtractor):
2455 session_path : pathlib.Path
2556 The absolute session path.
2657 task_collection : str
27- The raw task data collection
58+ The raw task data collection, e.g. 'raw_task_data_00'.
59+ default_path : str, pathlib.Path
60+ The default output folder relative to `session_path` (default: 'alf').
2861
2962 """
3063 var_names = ('laser_intervals' , 'laser_probability' , 'intervals' )
@@ -42,7 +75,13 @@ def _extract(self, extractor_classes=None, **kwargs) -> dict:
4275 """
4376 Extract the Bpod trial events.
4477
45- Saving of the datasets to file is handled by the superclass.
78+ The :meth:`BaseBpodTrialsExtractor._extract` method should be subclassed for doing the
79+ actual extraction, however it should be called indirectly via the
80+ :meth:`BaseBpodTrialsExtractor.extract` method. This superclass method has a `save` param
81+ which when true (default) will save the `var_names` data as `save_names` in the
82+ `default_path`. The `_extract` method should return a map of `var_names` to extracted data,
83+ and the superclass `extract` method will return these along with a list of full file paths
84+ if save=True (otherwise None).
4685
4786 Returns
4887 -------
@@ -56,6 +95,8 @@ def _extract(self, extractor_classes=None, **kwargs) -> dict:
5695
5796 Examples
5897 --------
98+ Below are some example snippets that you may want to put into the `_extract` method.
99+
59100 Get all detected TTLs. These should be stored for QC purposes
60101
61102 >>> self.frame2ttl, self.audio = raw.load_bpod_fronts(self.session_path, data=self.bpod_trials)
@@ -80,24 +121,57 @@ class TemplateTask(ChoiceWorldTrialsBpod):
80121 """A template behaviour task.
81122
82123 If the task protocol is a simple Bpod-only task (without an extra DAQ), you do not need a
83- separate behaviour task. Instead, create a new ibllib.io.extractors.BaseBpodTrialsExtractor
124+ separate behaviour task. Instead, create a new :class:` ibllib.io.extractors.BaseBpodTrialsExtractor`
84125 subclass (see above). You may need to create a custom Task if you want to run your own QC,
85126 however for this you can simply overload the `run_qc` method with your preferred QC class in
86127 the kwargs (see `projects.samuel_cuedBiasedChoiceWorld` for example).
128+
129+ To associate your task to the task protocol, add it to the
130+ :py:attr:`iblrig.base_tasks.BaseSession.extractor_tasks` list in your Session class. You can
131+ have separate pipeline Task classes for each DAQ you use, in which case name your classes
132+ whatever + sync label, e.g. 'TemplateTaskBpod', 'TemplateTaskNidq', 'TemplateTaskTimeline', etc.
133+ and simply add 'TemplateTask' to the extractor_tasks list and the pipeline will import the
134+ correct class depending on the DAQ used during that session.
87135 """
88136 cpu = 1
89137 io_charge = 90
90138 level = 1
91- signature = [
92- ('_ibl_trials.laserIntervals.npy' , 'alf' , True ),
93- ('_ibl_trials.laserProbability.npy' , 'alf' , True ),
94- ('_ibl_trials.intervals.npy' , 'alf' , True )]
95139
96- def extract_behavior (self , ** kwargs ):
140+ @property
141+ def signature (self ):
142+ """Define input and outputs required for this task.
143+
144+ This property returns dict of input files (those expected in order to extract data), and
145+ output files (those expected to be saved, registered and uploaded). The `collection` and
146+ `output_collection` properties are typically set automatically based on the experiment
147+ description file (defaults are 'raw_task_data_00' and 'alf', respectively). The boolean
148+ determines if the file is essential. An error if raised if these files aren't present
149+ before or after running the task, respectively.
150+
151+ The input_files may have a forth, optional value: a boolean indicating whether the input
152+ file should be registered and uploaded. This is useful if your task has extra raw data to
153+ upload.
154+ """
155+ signature = {
156+ 'input_files' : [
157+ ('_iblrig_taskData.raw.*' , self .collection , True ),
158+ ('_iblrig_taskSettings.raw.*' , self .collection , True ),
159+ ('_iblrig_encoderEvents.raw*' , self .collection , True ),
160+ ('_iblrig_encoderPositions.raw*' , self .collection , True )],
161+ 'output_files' : [
162+ ('*trials.laserIntervals.npy' , self .output_collection , True ),
163+ ('*trials.laserProbability.npy' , self .output_collection , False ),
164+ ('*trials.intervals.npy' , self .output_collection , False )]
165+ }
166+ return signature
167+
168+ def extract_behavior (self , save = True , ** kwargs ):
97169 """Extract the Bpod trials data.
98170
99171 Parameters
100172 ----------
173+ save : bool
174+ Whether to save the extracted data to disk.
101175 kwargs
102176
103177 Returns
@@ -108,7 +182,7 @@ def extract_behavior(self, **kwargs):
108182 The saved dataset filepaths.
109183 """
110184 # First determine the extractor from the task protocol
111- bpod_trials , out_files = ChoiceWorldTrialsBpod ._extract_behaviour (self , save = False , ** kwargs )
185+ bpod_trials , out_files = ChoiceWorldTrialsBpod .extract_behaviour (self , save = save , ** kwargs )
112186
113187 ... # further trials manipulation, etc.
114188 """
0 commit comments