Skip to content

Commit

Permalink
[ENH] Add BIDS URI option for IntendedFor mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
Dan Levitas committed Aug 20, 2024
1 parent 5a83cec commit 8ddf7f8
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 17 deletions.
6 changes: 6 additions & 0 deletions handler/convert.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 28 additions & 15 deletions handler/ezBIDS_core/ezBIDS_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,12 @@ def modify_uploaded_dataset_list(uploaded_img_list):
config_file = ""
exclude_data = False

config_file_list = natsorted([x for x in os.listdir(DATA_DIR) if x.endswith('ezBIDS_template.json')])
config_file_list = []
for root, dirs, files in os.walk(DATA_DIR):
for file in files:
if file.endswith('ezBIDS_template.json'):
config_file_list.append(os.path.join(root, file))

if len(config_file_list):
# Ideally only one config file uploaded, but if multiple configurations found, select last one (most recent?)
config = True
Expand Down Expand Up @@ -1392,7 +1397,7 @@ def determine_sub_ses_IDs(dataset_list, bids_compliant):
List of dictionaries containing pertinent and unique information about
the data, primarily coming from the metadata in the json files.
subjects_information : list
subs_information : list
List of dictionaries containing subject identification info, such as
PatientID, PatientName, PatientBirthDate, and corresponding session
information.
Expand All @@ -1402,7 +1407,7 @@ def determine_sub_ses_IDs(dataset_list, bids_compliant):
"""
date_counter = 1
subject_idx_counter = 0
subjects_information = []
subs_information = []
participants_info = {}
# Determine unique subjects from uploaded dataset
for sub in np.unique([x["subject"] for x in dataset_list]):
Expand Down Expand Up @@ -1550,9 +1555,9 @@ def determine_sub_ses_IDs(dataset_list, bids_compliant):
"validationErrors": []
}

subjects_information.append(subject_ids_info)
subs_information.append(subject_ids_info)

return dataset_list, subjects_information, participants_info
return dataset_list, subs_information, participants_info


def determine_unique_series(dataset_list, bids_compliant):
Expand Down Expand Up @@ -1638,15 +1643,15 @@ def determine_unique_series(dataset_list, bids_compliant):
return dataset_list, dataset_list_unique_series


def template_configuration(dataset_list_unique_series, subjects_information, config_file):
def template_configuration(dataset_list_unique_series, subs_information, config_file):
"""
Parameters
----------
dataset_list_unique_series : list of dictionaries
A modified version of dataset_list, where this list contains only the
dictionaries of acquisitions with a unique series group ID.
subjects_information : list
subs_information : list
List of dictionaries containing subject identification info, such as
PatientID, PatientName, PatientBirthDate, and corresponding session
information.
Expand All @@ -1669,13 +1674,16 @@ def template_configuration(dataset_list_unique_series, subjects_information, con
A modified version of dataset_list, where this list contains only the
dictionaries of acquisitions with a unique series group ID.
subjects_information : list
subs_information : list
List of dictionaries containing subject identification info, such as
PatientID, PatientName, PatientBirthDate, and corresponding session
information.
events : dictionary
Information pertaining to the events timing files for func/bold data.
bids_uri : boolean
Specifies whether or not user wants BIDS URI format for IntendedFor metadata mapping
"""

config_data = open(config_file)
Expand All @@ -1687,6 +1695,7 @@ def template_configuration(dataset_list_unique_series, subjects_information, con
subjects_sessions_info = config_data["subjects"]
config_dataset_list_unique_series = config_data["series"]
config_dataset_list_objects = config_data["objects"]
bids_uri = config_data["BIDSURI"]

# Try to determine subject (and session) mapping from what's in the configuration
match_start_index = None
Expand All @@ -1712,7 +1721,7 @@ def template_configuration(dataset_list_unique_series, subjects_information, con
"AcquisitionDateTime"
]

for sub_info in subjects_information:
for sub_info in subs_information:
sub = sub_info["subject"]
for key in ref_patient_info.keys():
if ref_subject_id in ref_patient_info[key]:
Expand Down Expand Up @@ -1819,7 +1828,7 @@ def template_configuration(dataset_list_unique_series, subjects_information, con
events["sampleValues"] = {}

return (readme, dataset_description_dic, participants_column_info,
dataset_list_unique_series, subjects_information, events)
dataset_list_unique_series, subs_information, events, bids_uri)


def create_lookup_info():
Expand Down Expand Up @@ -3106,15 +3115,15 @@ def check_dwi_b0maps(dataset_list_unique_series):
dataset_list = organize_dataset(dataset_list)

# Determine subject (and session) information
dataset_list, subjects_information, participants_info = determine_sub_ses_IDs(dataset_list, bids_compliant)
dataset_list, subs_information, participants_info = determine_sub_ses_IDs(dataset_list, bids_compliant)

# Make a new list containing the dictionaries of only unique dataset acquisitions
dataset_list, dataset_list_unique_series = determine_unique_series(dataset_list, bids_compliant)

# If ezBIDS configuration file detected in upload, use that for datatype, suffix, and entity identifications
if config is True:
readme, dataset_description_dic, participants_column_info, dataset_list_unique_series, subjects_information, events = \
template_configuration(dataset_list_unique_series, subjects_information, config_file)
readme, dataset_description_dic, participants_column_info, dataset_list_unique_series, subs_information, events, \
bids_uri = template_configuration(dataset_list_unique_series, subs_information, config_file)

else:
# README
Expand Down Expand Up @@ -3160,6 +3169,9 @@ def check_dwi_b0maps(dataset_list_unique_series):
}
}

# BIDS URI
bids_uri = False

# Generate lookup information directory to help with datatype and suffix identification (and to some degree, entities)
lookup_dic = create_lookup_info()

Expand Down Expand Up @@ -3212,12 +3224,13 @@ def check_dwi_b0maps(dataset_list_unique_series):
EZBIDS = {
"readme": readme,
"datasetDescription": dataset_description_dic,
"subjects": subjects_information,
"subjects": subs_information,
"participantsColumn": participants_column_info,
"participantsInfo": participants_info,
"series": ui_series_info_list,
"objects": objects_list,
"events": events
"events": events,
"BIDSURI": bids_uri
}

# Write dictionary to ezBIDS_core.json
Expand Down
1 change: 1 addition & 0 deletions ui/src/Finalize.vue
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ export default defineComponent({
//things that convert.ts uses
objects: this.ezbids.objects, //most important thing that convert.ts needs
BIDSURI: this.ezbids.BIDSURI,
events: this.ezbids.events,
entityMappings, //helps with convert
datasetDescription: this.ezbids.datasetDescription,
Expand Down
17 changes: 15 additions & 2 deletions ui/src/SeriesPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@
The information you specify here will be applied to all subjects that uses matching
SeriesDescription. You can also override this information later for each subject.
</p>
<el-checkbox v-model="this.ezbids.BIDSURI" @change="BIDSURI(this.ezbids, $event)">
<small>Use BIDS URI format for IntendedFor metadata mapping (if applicable)</small>
</el-checkbox>
<div style="background-color: white; padding: 10px; color: #666">
<i class="el-icon-back" /> &lt; Please select a series to view/edit
</div>
Expand Down Expand Up @@ -308,7 +311,7 @@ import ModalityForm from './components/modalityForm.vue';
import { prettyBytes } from './filters';
import { Series, IObject } from './store';
import { Series, IObject, IEzbids } from './store';
import { validateEntities, validate_B0FieldIdentifier_B0FieldSource, metadataAlerts } from './libUnsafe';
import anatYaml from '../src/assets/schema/rules/sidecars/anat.yaml';
Expand Down Expand Up @@ -378,6 +381,16 @@ export default defineComponent({
this.showInfo[entity] = !this.showInfo[entity];
},
BIDSURI($root: IEzbids, b: boolean) {
if (b === true) {
$root.BIDSURI = true;
localStorage.setItem('checkboxState', 'true');
} else {
$root.BIDSURI = false;
localStorage.setItem('checkboxState', 'false');
}
},
validate(s: Series | null) {
if (!s) return;
Expand All @@ -389,7 +402,7 @@ export default defineComponent({
validate_B0FieldIdentifier_B0FieldSource(s);
}
/* Alert users to metadata issues, such as missing required fields or
/* Alert users to metadata issues, such as missing required fields or
improperly-formmated metadata field values.
*/
let bidsDatatypeMetadata = {};
Expand Down
2 changes: 2 additions & 0 deletions ui/src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ const state = {
subjects: [] as Subject[],
series: [] as Series[],
objects: [] as IObject[],
BIDSURI: false,

_organized: [] as OrganizedSubject[], //above things are organized into subs/ses/run/object hierarchy for quick access

Expand Down Expand Up @@ -509,6 +510,7 @@ const store = createStore({
subjects: [],
series: [],
objects: [],
BIDSURI: false,

_organized: [], //above things are organized into subs/ses/run/object hierarchy for quick access

Expand Down

0 comments on commit 8ddf7f8

Please sign in to comment.