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

[ENH] Add BIDS URI option for IntendedFor mapping #131

Merged
merged 1 commit into from
Aug 20, 2024
Merged
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
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
Loading