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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: np_codeocean
3
- Version: 0.1.7
3
+ Version: 0.1.8
4
4
  Summary: Tools for uploading and interacting with Mindscope Neuropixels experiments on Code Ocean
5
5
  Author-Email: Ben Hardcastle <ben.hardcastle@alleninstitute.org>
6
6
  License: MIT
@@ -40,7 +40,7 @@ composite = [
40
40
 
41
41
  [project]
42
42
  name = "np_codeocean"
43
- version = "0.1.7"
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 files with folders that don't actually exist.
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('Creating modified structure.oebin')
93
- oebin_paths = dest.rglob('recording[0-9]*/structure.oebin')
94
- for oebin_path in oebin_paths:
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
- oebin_path.unlink()
107
- oebin_path.write_text(json.dumps(oebin_obj, indent=4))
108
- logger.debug('Overwrote symlink to structure.oebin with corrected strcuture.oebin')
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 | None) -> None:
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 | None) -> None:
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
- create_ephys_symlinks(upload.session, upload.ephys, recording_dirs=recording_dirs)
345
- create_behavior_symlinks(upload.session, upload.behavior)
346
- create_behavior_videos_symlinks(upload.session, upload.behavior_videos)
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