Skip to content

Commit d63e62b

Browse files
k1o0oliche
andauthored
Hotfix/2.34.1 (#758)
* Resolves iblenv#364 * Resolves #757 * Bump version * Bump version * pre-generated sequences extraction bugfix * Download required ap.meta files when building pipeline for task_qc command --------- Co-authored-by: olivier <[email protected]>
1 parent 462e8fb commit d63e62b

File tree

9 files changed

+149
-74
lines changed

9 files changed

+149
-74
lines changed

.github/workflows/ibllib_ci.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@ jobs:
3333
- name: Install deps
3434
run: |
3535
python -m pip install --upgrade pip
36-
python -m pip install flake8 pytest
36+
python -m pip install flake8 pytest flake8-docstrings
3737
pip install -r requirements.txt
3838
pip install -e .
3939
- name: Flake8
4040
run: |
4141
python -m flake8
42+
python -m flake8 --select D --ignore E ibllib/qc/camera.py
4243
- name: Brainbox tests
4344
run: |
4445
cd brainbox

ibllib/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import logging
33
import warnings
44

5-
__version__ = '2.34.0'
5+
__version__ = '2.34.1'
66
warnings.filterwarnings('always', category=DeprecationWarning, module='ibllib')
77

88
# if this becomes a full-blown library we should let the logging configuration to the discretion of the dev

ibllib/io/extractors/biased_trials.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,10 @@ def _extract(self, **kwargs):
4545

4646
@staticmethod
4747
def get_pregenerated_events(bpod_trials, settings):
48-
num = settings.get("PRELOADED_SESSION_NUM", None)
49-
if num is None:
50-
num = settings.get("PREGENERATED_SESSION_NUM", None)
48+
for k in ['PRELOADED_SESSION_NUM', 'PREGENERATED_SESSION_NUM', 'SESSION_TEMPLATE_ID']:
49+
num = settings.get(k, None)
50+
if num is not None:
51+
break
5152
if num is None:
5253
fn = settings.get('SESSION_LOADED_FILE_PATH', '')
5354
fn = PureWindowsPath(fn).name

ibllib/oneibl/data_handlers.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
from one.api import ONE
1616
from one.webclient import AlyxClient
17-
from one.util import filter_datasets
17+
from one.util import filter_datasets, ensure_list
1818
from one.alf.files import add_uuid_string, session_path_parts
1919
from ibllib.oneibl.registration import register_dataset, get_lab, get_local_data_repository
2020
from ibllib.oneibl.patcher import FTPPatcher, SDSCPatcher, SDSC_ROOT_PATH, SDSC_PATCH_PATH
@@ -140,8 +140,7 @@ def uploadData(self, outputs, version, clobber=False, **kwargs):
140140
versions = super().uploadData(outputs, version)
141141
data_repo = get_local_data_repository(self.one.alyx)
142142
# If clobber = False, do not re-upload the outputs that have already been processed
143-
if not isinstance(outputs, list):
144-
outputs = [outputs]
143+
outputs = ensure_list(outputs)
145144
to_upload = list(filter(None if clobber else lambda x: x not in self.processed, outputs))
146145
records = register_dataset(to_upload, one=self.one, versions=versions, repository=data_repo, **kwargs) or []
147146
if kwargs.get('dry', False):

ibllib/pipes/dynamic_pipeline.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,9 @@ def get_trials_tasks(session_path, one=None):
474474
# Check for an experiment.description file; ensure downloaded if possible
475475
if one and one.to_eid(session_path): # to_eid returns None if session not registered
476476
one.load_datasets(session_path, ['_ibl_experiment.description'], download_only=True, assert_present=False)
477+
# NB: meta files only required to build neuropixel tasks in make_pipeline
478+
if meta_files := one.list_datasets(session_path, '*.ap.meta', collection='raw_ephys_data*'):
479+
one.load_datasets(session_path, meta_files, download_only=True, assert_present=False)
477480
experiment_description = sess_params.read_params(session_path)
478481

479482
# If experiment description file then use this to make the pipeline

ibllib/pipes/mesoscope_tasks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ def _run(self, run_suite2p=True, rename_files=True, use_badframes=True, **kwargs
578578
""" Bad frames """
579579
qc_paths = (self.session_path.joinpath(f[1], 'exptQC.mat')
580580
for f in self.input_files if f[0] == 'exptQC.mat')
581-
qc_paths = map(str, filter(Path.exists, qc_paths))
581+
qc_paths = sorted(map(str, filter(Path.exists, qc_paths)))
582582
exptQC = [loadmat(p, squeeze_me=True, simplify_cells=True) for p in qc_paths]
583583
if len(exptQC) > 0:
584584
frameQC, frameQC_names, bad_frames = self._consolidate_exptQC(exptQC)

ibllib/qc/base.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@
1212

1313

1414
class QC:
15-
"""A base class for data quality control"""
15+
"""A base class for data quality control."""
1616

1717
def __init__(self, endpoint_id, one=None, log=None, endpoint='sessions'):
1818
"""
19+
A base class for data quality control.
20+
1921
:param endpoint_id: Eid for endpoint. If using sessions can also be a session path
2022
:param log: A logging.Logger instance, if None the 'ibllib' logger is used
2123
:param one: An ONE instance for fetching and setting the QC on Alyx
@@ -38,15 +40,17 @@ def __init__(self, endpoint_id, one=None, log=None, endpoint='sessions'):
3840

3941
@abstractmethod
4042
def run(self):
41-
"""Run the QC tests and return the outcome
43+
"""Run the QC tests and return the outcome.
44+
4245
:return: One of "CRITICAL", "FAIL", "WARNING" or "PASS"
4346
"""
4447
pass
4548

4649
@abstractmethod
4750
def load_data(self):
48-
"""Load the data required to compute the QC
49-
Subclasses may implement this for loading raw data
51+
"""Load the data required to compute the QC.
52+
53+
Subclasses may implement this for loading raw data.
5054
"""
5155
pass
5256

@@ -85,7 +89,8 @@ def overall_outcome(outcomes: iter, agg=max) -> spec.QC:
8589
return agg(map(spec.QC.validate, outcomes))
8690

8791
def _set_eid_or_path(self, session_path_or_eid):
88-
"""Parse a given eID or session path
92+
"""Parse a given eID or session path.
93+
8994
If a session UUID is given, resolves and stores the local path and vice versa
9095
:param session_path_or_eid: A session eid or path
9196
:return:
@@ -215,16 +220,16 @@ def update_extended_qc(self, data):
215220
return out
216221

217222
def compute_outcome_from_extended_qc(self) -> str:
218-
"""
219-
Returns the session outcome computed from aggregating the extended QC
220-
"""
223+
"""Return the session outcome computed from aggregating the extended QC."""
221224
details = self.one.alyx.get(f'/{self.endpoint}/{self.eid}', clobber=True)
222225
extended_qc = details['json']['extended_qc'] if self.json else details['extended_qc']
223226
return self.overall_outcome(v for k, v in extended_qc.items() or {} if k[0] != '_')
224227

225228

226229
def sign_off_dict(exp_dec, sign_off_categories=None):
227230
"""
231+
Create sign off dictionary.
232+
228233
Creates a dict containing 'sign off' keys for each device and task protocol in the provided
229234
experiment description.
230235

0 commit comments

Comments
 (0)