Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft for BIDS organize #1404

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 46 additions & 3 deletions dandi/organize.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@


dandi_path = op.join("sub-{subject_id}", "{dandi_filename}")
bids_path = op.join("sub-{subject_id}", "ses-{session_id}", "{bids_filename}")


def filter_invalid_metadata_rows(metadata_rows):
Expand All @@ -108,7 +109,9 @@


def create_unique_filenames_from_metadata(
metadata: list[dict], required_fields: Sequence[str] | None = None
metadata: list[dict],
required_fields: Sequence[str] | None = None,
style: str | None = None,
) -> list[dict]:
"""Create unique filenames given metadata

Expand Down Expand Up @@ -206,7 +209,12 @@
for r in metadata:
if r["dandi_path"] == conflicting_path:
r.setdefault("_required_if_not_empty", []).append(field)
_assign_dandi_names(metadata)
if style is None or style == "dandi":
_assign_dandi_names(metadata)
elif style == "bids":
_assign_bids_names(metadata)

Check warning on line 215 in dandi/organize.py

View check run for this annotation

Codecov / codecov/patch

dandi/organize.py#L214-L215

Added lines #L214 - L215 were not covered by tests
else:
lgr.error("“%s” is not a valid `dandi organize` style. ", style)

Check warning on line 217 in dandi/organize.py

View check run for this annotation

Codecov / codecov/patch

dandi/organize.py#L217

Added line #L217 was not covered by tests
non_unique = _get_non_unique_paths(metadata)
if not non_unique:
break
Expand Down Expand Up @@ -385,6 +393,38 @@
return value is None or (hasattr(value, "__len__") and not len(value))


def _assign_bids_names(metadata):
unique_values = _get_unique_values(metadata, dandi_layout_fields)

Check warning on line 397 in dandi/organize.py

View check run for this annotation

Codecov / codecov/patch

dandi/organize.py#L397

Added line #L397 was not covered by tests
# unless it is required, we would not include the fields with more than a
# single unique field
for r in metadata:
bids_filename = ""
for field, field_rec in dandi_layout_fields.items():
field_format = field_rec["format"]
field_type = field_rec.get("type", "additional")
if (

Check warning on line 405 in dandi/organize.py

View check run for this annotation

Codecov / codecov/patch

dandi/organize.py#L400-L405

Added lines #L400 - L405 were not covered by tests
(field_type == "required")
or (field_type == "additional" and len(unique_values[field]) > 1)
or (
field_type == "required_if_not_empty"
or (field in r.get("_required_if_not_empty", []))
)
):
value = r.get(field, None)
if is_undefined(value):

Check warning on line 414 in dandi/organize.py

View check run for this annotation

Codecov / codecov/patch

dandi/organize.py#L413-L414

Added lines #L413 - L414 were not covered by tests
# skip empty things
continue
if isinstance(value, (list, tuple)):
value = "+".join(map(str, value))

Check warning on line 418 in dandi/organize.py

View check run for this annotation

Codecov / codecov/patch

dandi/organize.py#L416-L418

Added lines #L416 - L418 were not covered by tests
# sanitize value to avoid undesired characters
value = _sanitize_value(value, field)

Check warning on line 420 in dandi/organize.py

View check run for this annotation

Codecov / codecov/patch

dandi/organize.py#L420

Added line #L420 was not covered by tests
# Format _key-value according to the "schema"
formatted_value = field_format.format(value)
bids_filename += formatted_value
r["bids_filename"] = bids_filename
Fixed Show fixed Hide fixed
r["bids_path"] = bids_path.format(**r)

Check warning on line 425 in dandi/organize.py

View check run for this annotation

Codecov / codecov/patch

dandi/organize.py#L422-L425

Added lines #L422 - L425 were not covered by tests
Fixed Show fixed Hide fixed


def _assign_dandi_names(metadata):
unique_values = _get_unique_values(metadata, dandi_layout_fields)
# unless it is required, we would not include the fields with more than a
Expand Down Expand Up @@ -750,6 +790,7 @@
def organize(
paths: Sequence[str],
dandiset_path: str | None = None,
style: str | None = None,
invalid: OrganizeInvalid = OrganizeInvalid.FAIL,
files_mode: FileOperationMode = FileOperationMode.AUTO,
devel_debug: bool = False,
Expand Down Expand Up @@ -903,7 +944,9 @@
files_mode = detect_link_type(link_test_file, dandiset_path)

metadata = create_unique_filenames_from_metadata(
metadata, required_fields=required_fields
metadata,
required_fields=required_fields,
style=style,
)

# update metadata with external_file information:
Expand Down