Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
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
58 changes: 30 additions & 28 deletions cubids/tests/test_bond.py
Original file line number Diff line number Diff line change
Expand Up @@ -508,45 +508,47 @@ def test_tsv_merge_changes(tmp_path):
assert str(orig.loc[row, "RenameEntitySet"]) != "nan"

# TESTING RENAMES GOT APPLIED
applied = pd.read_table(str(tmp_path / "unmodified_summary.tsv"))
applied_f = pd.read_table(str(tmp_path / "unmodified_files.tsv"))
applied_summary_df = pd.read_table(str(tmp_path / "unmodified_summary.tsv"))
applied_files_df = pd.read_table(str(tmp_path / "unmodified_files.tsv"))

# Check for inconsistencies between FilePath and KeyParamGroup
odd = []
for row in range(len(applied_f)):
if (
"VARIANT" in applied_f.loc[row, "FilePath"]
and "VARIANT" not in applied_f.loc[row, "KeyParamGroup"]
):
odd.append((applied_f.loc[row, "FilePath"]))
for _, row in applied_files_df.iterrows():
if "VARIANT" in row["FilePath"] and "VARIANT" not in row["KeyParamGroup"]:
odd.append(row["FilePath"])

# Track KeyParamGroups for files with inconsistencies
occurrences = {}
for row in range(len(applied_f)):
if applied_f.loc[row, "FilePath"] in odd:
if applied_f.loc[row, "FilePath"] in occurrences.keys():
occurrences[applied_f.loc[row, "FilePath"]].append(
applied_f.loc[row, "KeyParamGroup"]
)
for _, row in applied_files_df.iterrows():
fp = row["FilePath"]
if fp in odd:
if fp in occurrences.keys():
occurrences[fp].append(row["KeyParamGroup"])
else:
occurrences[applied_f.loc[row, "FilePath"]] = [applied_f.loc[row, "KeyParamGroup"]]
occurrences[fp] = [row["KeyParamGroup"]]

# Ensure no rows were lost
assert len(orig) == len(applied)
assert len(orig) == len(applied_summary_df)

# Check for exact matches in EntitySet
# Check that all the RenameEntitySet values are in the renamed entity sets
renamed = True
new_keys = applied["EntitySet"].tolist()
for row in range(len(orig)):
if orig.loc[row, "Modality"] != "fmap":
if (
str(orig.loc[row, "RenameEntitySet"]) != "nan"
and str(orig.loc[row, "RenameEntitySet"]) not in new_keys
):
print(orig.loc[row, "RenameEntitySet"])
renamed = False

assert renamed
new_keys = applied_summary_df["EntitySet"].tolist()
for _, row in orig.iterrows():
if row["Modality"] == "fmap":
# Ignore field map renaming
continue

res = row["RenameEntitySet"]
if isinstance(res, str) and (res != "nan") and (res not in new_keys):
print("HI")
print(res)
print("DONE")
renamed = False

print("\n".join(new_keys))
print("DONE2")

assert renamed, orig["RenameEntitySet"].tolist()

# will no longer be equal because of auto rename!
assert file_hash(original_summary_tsv) != file_hash(tmp_path / "unmodified_summary.tsv")
Expand Down
14 changes: 7 additions & 7 deletions cubids/tests/test_variants.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ def test_assign_variants_with_cluster_values(base_df):
result = assign_variants(base_df, ["EchoTime"])

# Check that variant names include cluster values
assert "acquisition-VARIANTEchoTimeC2_" in result.loc[1, "RenameEntitySet"]
assert "acquisition-VARIANTEchoTimeC3_" in result.loc[2, "RenameEntitySet"]
assert "acquisition-VARIANT+EchoTimeC2_" in result.loc[1, "RenameEntitySet"]
assert "acquisition-VARIANT+EchoTimeC3_" in result.loc[2, "RenameEntitySet"]


def test_assign_variants_mixed_parameters(base_df):
Expand All @@ -64,8 +64,8 @@ def test_assign_variants_mixed_parameters(base_df):
result = assign_variants(base_df, ["EchoTime", "FlipAngle"])

# Check variant names include both cluster values and actual values
assert "acquisition-VARIANTEchoTimeC2FlipAngle75_" in result.loc[1, "RenameEntitySet"]
assert "acquisition-VARIANTEchoTimeC3FlipAngle60_" in result.loc[2, "RenameEntitySet"]
assert "acquisition-VARIANT+EchoTimeC2+FlipAngle75_" in result.loc[1, "RenameEntitySet"]
assert "acquisition-VARIANT+EchoTimeC3+FlipAngle60_" in result.loc[2, "RenameEntitySet"]


def test_assign_variants_special_parameters(base_df):
Expand All @@ -78,6 +78,6 @@ def test_assign_variants_special_parameters(base_df):
result = assign_variants(base_df, ["HasFieldmap", "UsedAsFieldmap"])

# Check special parameter handling
assert "acquisition-VARIANTOther_" in result.loc[0, "RenameEntitySet"]
assert "acquisition-VARIANTNoFmapIsUsed_" in result.loc[1, "RenameEntitySet"]
assert "acquisition-VARIANTNoFmap_" in result.loc[2, "RenameEntitySet"]
assert "acquisition-VARIANT+Other_" in result.loc[0, "RenameEntitySet"]
assert "acquisition-VARIANT+NoFmap+IsUsed_" in result.loc[1, "RenameEntitySet"]
assert "acquisition-VARIANT+NoFmap_" in result.loc[2, "RenameEntitySet"]
31 changes: 18 additions & 13 deletions cubids/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ def _file_to_entity_set(filename):
Field maps will have an extraneous "fmap" entity.
>>> _file_to_entity_set("sub-01_ses-01_dir-AP_epi.nii.gz")
'direction-AP_fmap-epi_session-01_suffix-epi'

Plus signs are supported.
>>> _file_to_entity_set("sub-01_ses-01_acq-VARIANT+EchoTimeC1_epi.nii.gz")
'acquisition-VARIANT+EchoTimeC1_session-01_suffix-epi'
"""
entities = parse_file_entities(str(filename))
return _entities_to_entity_set(entities)
Expand Down Expand Up @@ -934,7 +938,11 @@ def assign_variants(summary, rename_cols):
renamed = True

if summary.loc[row, "ParamGroup"] != 1 and not renamed:
acq_str = "VARIANT"
orig_acq = entities.get("acquisition", "")
if orig_acq == "":
acq_str = "VARIANT"
else:
acq_str = f"{orig_acq}+VARIANT"
# now we know we have a deviant param group
# check if TR is same as param group 1
entity_set = summary.loc[row, "EntitySet"]
Expand All @@ -951,19 +959,19 @@ def assign_variants(summary, rename_cols):
cluster_val = 0

if cluster_val != dom_entity_set[f"Cluster_{col}"]:
acq_str += f"{col}C{int(cluster_val)}"
acq_str += f"+{col}C{int(cluster_val)}"

elif summary.loc[row, col] != dom_entity_set[col]:
if col == "HasFieldmap":
if dom_entity_set[col] == "True":
acq_str += "NoFmap"
acq_str += "+NoFmap"
else:
acq_str += "HasFmap"
acq_str += "+HasFmap"
elif col == "UsedAsFieldmap":
if dom_entity_set[col] == "True":
acq_str += "Unused"
acq_str += "+Unused"
else:
acq_str += "IsUsed"
acq_str += "+IsUsed"
else:
val = summary.loc[row, col]
# If the value is a string float (contains decimal point)
Expand All @@ -972,18 +980,15 @@ def assign_variants(summary, rename_cols):
# If the value is an actual float
elif isinstance(val, float):
val = str(val).replace(".", "p")
acq_str += f"{col}{val}"
acq_str += f"+{col}{val}"

if acq_str == "VARIANT":
acq_str += "Other"
acq_str += "+Other"

acq = f"acquisition-{acq_str}"
if "acquisition" in entities.keys():
acq = f"acquisition-{entities['acquisition'] + acq_str}"
new_name = summary.loc[row, "EntitySet"].replace(
f"acquisition-{entities['acquisition']}", acq
)
new_name = summary.loc[row, "EntitySet"].replace(f"acquisition-{orig_acq}", acq)
else:
acq = f"acquisition-{acq_str}"
new_name = acq + "_" + summary.loc[row, "EntitySet"]

summary.at[row, "RenameEntitySet"] = new_name
Expand Down
10 changes: 5 additions & 5 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -184,23 +184,23 @@ CuBIDS populates this column for all Variant Groups
Specifically, CuBIDS will suggest renaming all non-dominant Parameter Groups to include ``VARIANT*``
in their acquisition field where ``*`` indicates how the Parameter Group varies from the Dominant Group:

1. For clustered parameters (like EchoTime), the cluster number is used (e.g., ``VARIANTEchoTime2``)
2. For regular parameters (like FlipAngle), the actual value is used (e.g., ``VARIANTFlipAngle75``)
1. For clustered parameters (like EchoTime), the cluster number is used (e.g., ``VARIANT+EchoTimeC2``)
2. For regular parameters (like FlipAngle), the actual value is used (e.g., ``VARIANT+FlipAngle75``)
3. For special parameters:
- HasFieldmap variations use ``NoFmap`` or ``HasFmap``
- UsedAsFieldmap variations use ``Unused`` or ``IsUsed``

For example, when CuBIDS encounters a Parameter Group with a clustered EchoTime that varies from
the one present in the Dominant Group, it will automatically suggest renaming all scans in that
Variant Group to include ``acquisition-VARIANTEchoTime2`` in their filenames (if the scan belongs
Variant Group to include ``acquisition-VARIANT+EchoTimeC2`` in their filenames (if the scan belongs
to cluster 2).

When multiple parameters vary, their names are concatenated (e.g., ``VARIANTEchoTime2FlipAngle75``).
When multiple parameters vary, their names are concatenated (e.g., ``VARIANT+EchoTimeC2+FlipAngle75``).
When the user runs ``cubids apply``, filenames will get renamed according to the auto-generated
names in the "Rename Entity Set" column in the summary.tsv

.. note::
The above behavior is new as of version 1.2.0. Prior to this, the variant name was just ``VARIANT{parameter}``.
The above behavior is new as of version 1.2.0. Prior to this, the variant name was just ``VARIANT+{parameter}``.


Deleting a mistake
Expand Down