np_codeocean 0.1.7__tar.gz → 0.1.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {np_codeocean-0.1.7 → np_codeocean-0.1.8}/PKG-INFO +1 -1
- {np_codeocean-0.1.7 → np_codeocean-0.1.8}/pyproject.toml +1 -1
- {np_codeocean-0.1.7 → np_codeocean-0.1.8}/src/np_codeocean/upload.py +26 -22
- {np_codeocean-0.1.7 → np_codeocean-0.1.8}/README.md +0 -0
- {np_codeocean-0.1.7 → np_codeocean-0.1.8}/src/np_codeocean/__init__.py +0 -0
- {np_codeocean-0.1.7 → np_codeocean-0.1.8}/src/np_codeocean/scripts/upload_sessions.py +0 -0
- {np_codeocean-0.1.7 → np_codeocean-0.1.8}/src/np_codeocean/upload_one.py +0 -0
- {np_codeocean-0.1.7 → np_codeocean-0.1.8}/src/np_codeocean/utils.py +0 -0
|
@@ -40,7 +40,7 @@ composite = [
|
|
|
40
40
|
|
|
41
41
|
[project]
|
|
42
42
|
name = "np_codeocean"
|
|
43
|
-
version = "0.1.
|
|
43
|
+
version = "0.1.8"
|
|
44
44
|
description = "Tools for uploading and interacting with Mindscope Neuropixels experiments on Code Ocean"
|
|
45
45
|
authors = [
|
|
46
46
|
{ name = "Ben Hardcastle", email = "ben.hardcastle@alleninstitute.org" },
|
|
@@ -87,25 +87,33 @@ def create_ephys_symlinks(session: np_session.Session, dest: Path,
|
|
|
87
87
|
|
|
88
88
|
def correct_structure(dest: Path) -> None:
|
|
89
89
|
"""
|
|
90
|
-
In case some probes are missing, remove device entries from structure.oebin
|
|
90
|
+
In case some probes are missing, remove device entries from structure.oebin
|
|
91
|
+
files for devices with folders that have not been preserved.
|
|
91
92
|
"""
|
|
92
|
-
logger.debug('
|
|
93
|
-
|
|
94
|
-
for
|
|
93
|
+
logger.debug('Checking structure.oebin for missing folders...')
|
|
94
|
+
recording_dirs = dest.rglob('recording[0-9]')
|
|
95
|
+
for recording_dir in recording_dirs:
|
|
96
|
+
if not recording_dir.is_dir():
|
|
97
|
+
continue
|
|
98
|
+
oebin_path = recording_dir / 'structure.oebin'
|
|
99
|
+
if not (oebin_path.is_symlink() or oebin_path.exists()):
|
|
100
|
+
logger.warning(f'No structure.oebin found in {recording_dir}')
|
|
101
|
+
continue
|
|
95
102
|
logger.debug(f'Examining oebin: {oebin_path} for correction')
|
|
96
103
|
oebin_obj = np_tools.read_oebin(np_config.normalize_path(oebin_path.readlink()))
|
|
97
|
-
|
|
98
|
-
for subdir_name in ('events', 'continuous'):
|
|
104
|
+
any_removed = False
|
|
105
|
+
for subdir_name in ('events', 'continuous'):
|
|
99
106
|
subdir = oebin_path.parent / subdir_name
|
|
100
107
|
# iterate over copy of list so as to not disrupt iteration when elements are removed
|
|
101
108
|
for device in [device for device in oebin_obj[subdir_name]]:
|
|
102
109
|
if not (subdir / device['folder_name']).exists():
|
|
103
110
|
logger.info(f'{device["folder_name"]} not found in {subdir}, removing from structure.oebin')
|
|
104
111
|
oebin_obj[subdir_name].remove(device)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
112
|
+
any_removed = True
|
|
113
|
+
if any_removed:
|
|
114
|
+
oebin_path.unlink()
|
|
115
|
+
oebin_path.write_text(json.dumps(oebin_obj, indent=4))
|
|
116
|
+
logger.debug('Overwrote symlink to structure.oebin with corrected strcuture.oebin')
|
|
109
117
|
|
|
110
118
|
def is_behavior_video_file(path: Path) -> bool:
|
|
111
119
|
if path.is_dir() or path.suffix not in ('.mp4', '.avi', '.json'):
|
|
@@ -115,13 +123,10 @@ def is_behavior_video_file(path: Path) -> bool:
|
|
|
115
123
|
return True
|
|
116
124
|
return False
|
|
117
125
|
|
|
118
|
-
def create_behavior_symlinks(session: np_session.Session, dest: Path
|
|
126
|
+
def create_behavior_symlinks(session: np_session.Session, dest: Path) -> None:
|
|
119
127
|
"""Create symlinks in `dest` pointing to files in top-level of session
|
|
120
128
|
folder on np-exp, plus all files in `exp` subfolder, if present.
|
|
121
129
|
"""
|
|
122
|
-
if dest is None:
|
|
123
|
-
logger.debug(f"No behavior folder supplied for {session}")
|
|
124
|
-
return
|
|
125
130
|
subfolder_names = ('exp', 'qc')
|
|
126
131
|
logger.info(f'Creating symlinks in {dest} to files in {session.npexp_path}...')
|
|
127
132
|
for src in session.npexp_path.glob('*'):
|
|
@@ -138,13 +143,10 @@ def create_behavior_symlinks(session: np_session.Session, dest: Path | None) ->
|
|
|
138
143
|
np_tools.symlink(as_posix(src), dest / src.relative_to(session.npexp_path))
|
|
139
144
|
logger.debug(f'Finished creating symlinks to {name!r} files')
|
|
140
145
|
|
|
141
|
-
def create_behavior_videos_symlinks(session: np_session.Session, dest: Path
|
|
146
|
+
def create_behavior_videos_symlinks(session: np_session.Session, dest: Path) -> None:
|
|
142
147
|
"""Create symlinks in `dest` pointing to MVR video files and info jsons in top-level of session
|
|
143
148
|
folder on np-exp.
|
|
144
149
|
"""
|
|
145
|
-
if dest is None:
|
|
146
|
-
logger.debug(f"No behavior_videos folder supplied for {session}")
|
|
147
|
-
return
|
|
148
150
|
logger.info(f'Creating symlinks in {dest} to files in {session.npexp_path}...')
|
|
149
151
|
for src in session.npexp_path.glob('*'):
|
|
150
152
|
if is_behavior_video_file(src):
|
|
@@ -340,10 +342,12 @@ def create_codeocean_upload(session: str | int | np_session.Session,
|
|
|
340
342
|
job = np_config.normalize_path(root / 'upload.csv'),
|
|
341
343
|
force_cloud_sync=force_cloud_sync,
|
|
342
344
|
)
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
345
|
+
if upload.ephys:
|
|
346
|
+
create_ephys_symlinks(upload.session, upload.ephys, recording_dirs=recording_dirs)
|
|
347
|
+
if upload.behavior:
|
|
348
|
+
create_behavior_symlinks(upload.session, upload.behavior)
|
|
349
|
+
if upload.behavior_videos:
|
|
350
|
+
create_behavior_videos_symlinks(upload.session, upload.behavior_videos)
|
|
347
351
|
create_upload_job(upload)
|
|
348
352
|
return upload
|
|
349
353
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|