From 4b1425f4dac032259304dd0ff3d6425d07e0c5fb Mon Sep 17 00:00:00 2001 From: Marcel Zwiers Date: Sat, 13 Jul 2024 23:30:14 +0200 Subject: [PATCH] Add some logging when adding run-items + minor tweaks --- bidscoin/bcoin.py | 6 +++--- bidscoin/bids.py | 4 ++-- bidscoin/bidseditor.py | 5 ++++- bidscoin/plugins/dcm2niix2bids.py | 2 +- docs/troubleshooting.rst | 2 +- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/bidscoin/bcoin.py b/bidscoin/bcoin.py index 7fd223ca..1aa694d5 100755 --- a/bidscoin/bcoin.py +++ b/bidscoin/bcoin.py @@ -95,9 +95,9 @@ def synchronize(pbatch, jobids: list, wait: int=15): done = 0 while done < len(jobids): jobs = [pbatch.jobStatus(jobid) for jobid in jobids] - done = sum([status in ('done', 'failed', 'undetermined') for status in jobs]) - qbar.n = sum([status == 'queued_active' for status in jobs]) - rbar.n = sum([status == 'running' for status in jobs]) + done = sum(status in ('done', 'failed', 'undetermined') for status in jobs) + qbar.n = sum(status == 'queued_active' for status in jobs) + rbar.n = sum(status == 'running' for status in jobs) qbar.refresh(), rbar.refresh() time.sleep(2) qbar.close(), rbar.close() diff --git a/bidscoin/bids.py b/bidscoin/bids.py index b540f9cd..c35ac238 100644 --- a/bidscoin/bids.py +++ b/bidscoin/bids.py @@ -1736,7 +1736,7 @@ def get_matching_run(datasource: DataSource, bidsmap: Bidsmap, runtime=False) -> datasource.datatype = datatype for run in runs or []: - match = any([run[matching][attrkey] not in [None,''] for matching in ('properties','attributes') for attrkey in run[matching]]) # Normally match==True, but make match==False if all attributes are empty + match = any(run[matching][attrkey] not in [None,''] for matching in ('properties','attributes') for attrkey in run[matching]) # Normally match==True, but make match==False if all attributes are empty run_ = create_run(datasource, bidsmap) # Try to see if the sourcefile matches all the filesystem properties @@ -2071,7 +2071,7 @@ def check_runindices(session: Path) -> bool: if not (pd.isna(scans_table.loc[scan, 'acq_time']) or pd.isna(scans_table.loc[prevscan, 'acq_time'])): acq_time = datetime.datetime.fromisoformat(scans_table.loc[scan, 'acq_time']) acq_prev = datetime.datetime.fromisoformat(scans_table.loc[prevscan, 'acq_time']) - if (acq_time - acq_prev).total_seconds() <= 0: + if (acq_time - acq_prev).total_seconds() < 0: LOGGER.warning(f"Acquisition times do not increase with the run-indices. Please check `{scans_tsv}`") return False diff --git a/bidscoin/bidseditor.py b/bidscoin/bidseditor.py index d26e6b48..bf941a1b 100755 --- a/bidscoin/bidseditor.py +++ b/bidscoin/bidseditor.py @@ -236,11 +236,14 @@ def show_contextmenu(self, pos): run = bids.get_run(self.template_bidsmap, datatype, 0, datasource) run['properties']['filepath'] = datasource.properties('filepath') # Make the added run a strict match (i.e. an exception) run['properties']['filename'] = datasource.properties('filename') # Make the added run a strict match (i.e. an exception) + LOGGER.verbose(f"Expert usage: User adds run-item {dataformat}[{datatype}]: {filename}") + if Path(filename) in bids.dir_bidsmap(self.output_bidsmap, dataformat): + LOGGER.warning(f"Added run-item {dataformat}[{datatype}]: {filename} already exists") bids.insert_run(self.output_bidsmap, run, 0) # Put the run at the front (so it gets matching priority) if dataformat not in self.ordered_file_index: self.ordered_file_index[dataformat] = {datasource.path: 0} else: - self.ordered_file_index[dataformat][datasource.path] = max([self.ordered_file_index[dataformat][fname] for fname in self.ordered_file_index[dataformat]]) + 1 + self.ordered_file_index[dataformat][datasource.path] = max(self.ordered_file_index[dataformat][fname] for fname in self.ordered_file_index[dataformat]) + 1 if datasource.is_datasource(): self.update_subses_samples(self.output_bidsmap, dataformat) diff --git a/bidscoin/plugins/dcm2niix2bids.py b/bidscoin/plugins/dcm2niix2bids.py index 66940757..f6a72f99 100644 --- a/bidscoin/plugins/dcm2niix2bids.py +++ b/bidscoin/plugins/dcm2niix2bids.py @@ -370,7 +370,7 @@ def bidscoiner_plugin(session: Path, bidsmap: Bidsmap, bidsses: Path) -> Union[N # Check if there are files that got additional postfixes from dcm2niix. See: https://github.com/rordenlab/dcm2niix/blob/master/FILENAMING.md dcm2niixpostfixes = ('_c', '_i', '_Eq', '_real', '_imaginary', '_MoCo', '_t', '_Tilt', '_e', '_ph', '_ADC', '_fieldmaphz') #_c%d, _e%d and _ph (and any combination of these in that order) are for multi-coil data, multi-echo data and phase data - dcm2niixfiles = sorted(set([dcm2niixfile for dcm2niixpostfix in dcm2niixpostfixes for dcm2niixfile in outfolder.glob(f"{bidsname}*{dcm2niixpostfix}*.nii*")])) + dcm2niixfiles = sorted(set(dcm2niixfile for dcm2niixpostfix in dcm2niixpostfixes for dcm2niixfile in outfolder.glob(f"{bidsname}*{dcm2niixpostfix}*.nii*"))) dcm2niixfiles = [dcm2niixfile for dcm2niixfile in dcm2niixfiles if not (re.match(r'sub-.*_echo-[0-9]*\.nii', dcm2niixfile.name) or re.match(r'sub-.*_phase(diff|[12])\.nii', dcm2niixfile.name))] # Skip false-positive (-> glob) dcm2niixfiles, e.g. postfix = 'echo-1' (see GitHub issue #232) diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst index ba968d1a..f407e322 100644 --- a/docs/troubleshooting.rst +++ b/docs/troubleshooting.rst @@ -137,7 +137,7 @@ The data of some subjects need to be treated (mapped) differently ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Sometimes you may have irregularities in your data that make that you would like make exceptions for run-items of certain subjects. There are different ways to do this but most likely the best way to do this is to add a json sidecar file to the source data of those run-items. In the json sidecar file you can store an attribute key-value pair to `overrule or extend the original attribute value of the source data <./bidsmap.html#structure-and-content>`__. For instance, if your fMRI run was acquired with the wrong task presentation, e.g. ``task2`` instead of ``task1``, you can add ``SeriesDescription: task2`` to the sidecar file to overrule ``SeriesDescription: task1`` in the DICOM header (to make a more specific exception that shows up as a new run-item in the bidsmap you can change it to e.g. ``task1_exception``). -An alternative way to make exceptions is to manually insert run-items using the ``Add`` context menu-item in the main window of the bidseditor (right-click on the selected BIDS output names). After you selected the irregular source data files you can then set the data type and BIDS entities just for these data sources. The way this works is that, as opposed to regular run-items, the ``filepath`` and ``filename`` properties are explicitly specified (so they do not match with other data sources; surely you can still edit them and add e.g. regular expression patterns to tweak your results). You can see the explicit values in the properties table in the screenshot below, and when you edit your added run-items. Finally, the added run-items are put at the front of the lists, so they get (run-item matching) priority when mapping your source data to BIDS. +An alternative way to make exceptions is to manually insert run-items using the ``Add`` context menu-item in the main window of the bidseditor (right-click on the selected BIDS output names). After you selected the irregular source data file(s) (NB: always select the first file in the source folder) you can then set the data type and BIDS entities just for these data sources. The way this works is that, as opposed to regular run-items, the ``filepath`` and ``filename`` properties are explicitly specified (so they do not match with other data sources; surely you can still edit them and add e.g. regular expression patterns to tweak your results). You can see the explicit values in the properties table in the screenshot below, and when you edit the added run-items. Finally, the added run-items are put at the front of the lists, so they get (run-item matching) priority when mapping your source data to BIDS. .. figure:: ./_static/bidseditor_added_run.png