From 37679c09c49666fd259fa1ebebc84cfe86c4bba5 Mon Sep 17 00:00:00 2001 From: Ali Khan Date: Mon, 18 Nov 2024 11:04:27 -0500 Subject: [PATCH 1/3] update cfmm_base to accept 'NONE' in addition to 'ND' to indicate no distortion correction applied - note: should confirm this is the case. --- heuristics/cfmm_base.py | 52 ++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/heuristics/cfmm_base.py b/heuristics/cfmm_base.py index 654db27..6fcb627 100644 --- a/heuristics/cfmm_base.py +++ b/heuristics/cfmm_base.py @@ -322,17 +322,17 @@ def infotodict(seqinfo): info[DIS2D_inv1_mp2rage].append({'item': s.series_id}) if ('DIS3D' in (s.image_type[3].strip())): info[DIS3D_inv1_mp2rage].append({'item': s.series_id}) - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[inv1_mp2rage].append({'item': s.series_id}) if ('T1_Images' in (s.series_description).strip()): if ('DIS2D' in (s.image_type[3].strip())): info[DIS2D_t1map].append({'item': s.series_id}) if ('DIS3D' in (s.image_type[3].strip())): info[DIS3D_t1map].append({'item': s.series_id}) - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[t1map].append({'item': s.series_id}) if ('UNI-DEN' in (s.series_description).strip()): - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[t1w].append({'item': s.series_id}) elif ('DIS2D' in (s.image_type[4].strip())): info[DIS2D_t1w].append({'item': s.series_id}) @@ -343,14 +343,14 @@ def infotodict(seqinfo): info[DIS2D_uni_mp2rage].append({'item': s.series_id}) if ('DIS3D' in s.image_type): info[DIS3D_uni_mp2rage].append({'item': s.series_id}) - if ('ND' in s.image_type): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[uni_mp2rage].append({'item': s.series_id}) if ('_INV2' in (s.series_description).strip()): if ('DIS2D' in (s.image_type[3].strip())): info[DIS2D_inv2_mp2rage].append({'item': s.series_id}) if ('DIS3D' in (s.image_type[3].strip())): info[DIS3D_inv2_mp2rage].append({'item': s.series_id}) - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[inv2_mp2rage].append({'item': s.series_id}) @@ -359,7 +359,7 @@ def infotodict(seqinfo): info[DIS2D_t1w_mprage].append({'item': s.series_id}) if ('DIS3D' in (s.image_type[3].strip())): info[DIS3D_t1w_mprage].append({'item': s.series_id}) - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[t1w_mprage].append({'item': s.series_id}) @@ -375,7 +375,7 @@ def infotodict(seqinfo): #sa2rage if ('sa2rage' in s.series_description): - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): if ('invContrast1' in s.series_description or 'INV1' in s.series_description): info[inv_1_sa2rage] = [s.series_id] if ('invContrast2' in s.series_description or 'INV2' in s.series_description): @@ -403,7 +403,7 @@ def infotodict(seqinfo): if ('pd_t2_tse_tra' in s.series_description or 'pd+t2_tse_tra' in s.series_description): - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[pd_t2_tse_tra].append({'item': s.series_id}) if ('DIS3D' in (s.image_type[3].strip())): info[DIS3D_pd_t2_tse_tra].append({'item': s.series_id}) @@ -413,7 +413,7 @@ def infotodict(seqinfo): #tse cor T2w elif ('pd_t2_tse_cor' in s.series_description or 'pd+t2_tse_cor' in s.series_description): - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[pd_t2_tse_cor].append({'item': s.series_id}) if ('DIS3D' in (s.image_type[3].strip())): info[DIS3D_pd_t2_tse_cor].append({'item': s.series_id}) @@ -421,7 +421,7 @@ def infotodict(seqinfo): info[DIS2D_pd_t2_tse_cor].append({'item': s.series_id}) elif ('pd_t2_tse' in s.series_description or 'pd+t2_tse' in s.series_description): - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[pd_t2_tse].append({'item': s.series_id}) if ('DIS3D' in (s.image_type[3].strip())): info[DIS3D_pd_t2_tse].append({'item': s.series_id}) @@ -431,7 +431,7 @@ def infotodict(seqinfo): elif ('t2_tse_tra' in s.series_description): - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[t2_tse_tra].append({'item': s.series_id}) if ('DIS3D' in (s.image_type[3].strip())): info[DIS3D_t2_tse_tra].append({'item': s.series_id}) @@ -441,7 +441,7 @@ def infotodict(seqinfo): #tse cor T2w elif ('t2_tse_cor' in s.series_description): - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[t2_tse_cor].append({'item': s.series_id}) if ('DIS3D' in (s.image_type[3].strip())): info[DIS3D_t2_tse_cor].append({'item': s.series_id}) @@ -450,7 +450,7 @@ def infotodict(seqinfo): elif ('t2_tse' in s.series_description): - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[t2_tse].append({'item': s.series_id}) if ('DIS3D' in (s.image_type[3].strip())): info[DIS3D_t2_tse].append({'item': s.series_id}) @@ -458,7 +458,7 @@ def infotodict(seqinfo): info[DIS2D_t2_tse].append({'item': s.series_id}) if ('pd_tse_tra' in s.series_description): - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[pd_tse_tra].append({'item': s.series_id}) if ('DIS3D' in (s.image_type[3].strip())): info[DIS3D_pd_tse_tra].append({'item': s.series_id}) @@ -468,7 +468,7 @@ def infotodict(seqinfo): #tse cor T2w elif ('pd_tse_cor' in s.series_description): - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[pd_tse_cor].append({'item': s.series_id}) if ('DIS3D' in (s.image_type[3].strip())): info[DIS3D_pd_tse_cor].append({'item': s.series_id}) @@ -477,7 +477,7 @@ def infotodict(seqinfo): elif ('pd_tse' in s.series_description): - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[pd_tse].append({'item': s.series_id}) if ('DIS3D' in (s.image_type[3].strip())): info[DIS3D_pd_tse].append({'item': s.series_id}) @@ -509,7 +509,7 @@ def infotodict(seqinfo): #susceptibility ND multiecho if ('susc' in s.series_description or 'gre3d' in s.series_description or 't1_fl3d_p4_iso' in s.series_description ): if ('M' in (s.image_type[2].strip())): - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[mag_echo_GRE] = [s.series_id] if ('DIS2D' in (s.image_type[3].strip())): info[DIS2D_mag_echo_GRE] = [s.series_id] @@ -517,7 +517,7 @@ def infotodict(seqinfo): info[DIS3D_mag_echo_GRE] = [s.series_id] if ('P' in (s.image_type[2].strip())): - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[phase_echo_GRE] = [s.series_id] if ('DIS2D' in (s.image_type[3].strip())): info[DIS2D_phase_echo_GRE] = [s.series_id] @@ -544,19 +544,19 @@ def infotodict(seqinfo): #multi-echo GRE with compressed sensing if ('gre_CS_C41' in s.series_description): if ('M' in (s.image_type[2].strip())): - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[mag_echo_CS_GRE] = [s.series_id] if ('P' in (s.image_type[2].strip())): - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[phase_echo_CS_GRE] = [s.series_id] # MTon GRE (excludes phase image since not needed) if ('gre_ptx_MT_On' in s.series_description ): if ('M' in (s.image_type[2].strip())): - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[mag_MT_on_GRE].append({'item': s.series_id}) if ('DIS2D' in (s.image_type[3].strip())): info[DIS2D_mag_MT_on_GRE].append({'item': s.series_id}) @@ -565,7 +565,7 @@ def infotodict(seqinfo): #MToff GRE if ('gre_ptx_MT_Off' in s.series_description ): if ('M' in (s.image_type[2].strip())): - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[mag_MT_off_GRE].append({'item': s.series_id}) if ('DIS2D' in (s.image_type[3].strip())): info[DIS2D_mag_MT_off_GRE].append({'item': s.series_id}) @@ -576,7 +576,7 @@ def infotodict(seqinfo): #T2star if ('T2Star' in s.series_description): - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[T2_star].append({'item': s.series_id}) if ('DIS2D' in (s.image_type[3].strip())): info[DIS2D_T2_star].append({'item': s.series_id}) @@ -586,7 +586,7 @@ def infotodict(seqinfo): #spc T2w if ('spc_T2' in s.series_description or 'T2w_SPC' in s.series_description or 'T2w_space' in s.series_description or 't2_space' in s.series_description or 't2_spc' in s.series_description or 'T2_spc' in s.series_description.strip() ): if ('dark-fluid' not in s.series_description ): - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[spc_T2w].append({'item': s.series_id}) if ('DIS2D' in (s.image_type[3].strip())): info[DIS2D_spc_T2w].append({'item': s.series_id}) @@ -595,7 +595,7 @@ def infotodict(seqinfo): #spc FLAIR if ('spc_flair' in s.series_description or 'flair_spc' in s.series_description or 'dark-fluid' in s.series_description): - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[spc_FLAIR].append({'item': s.series_id}) if ('DIS2D' in (s.image_type[3].strip())): info[DIS2D_spc_FLAIR].append({'item': s.series_id}) @@ -605,7 +605,7 @@ def infotodict(seqinfo): #TOF angio if ('3D_TOF' in s.series_description or 'tof_fl3d' in s.series_description): if (s.dim3>1): - if ('ND' in (s.image_type[3].strip())): + if ('ND' in (s.image_type[3].strip()) or 'NONE' in (s.image_type[3].strip())): info[TOF_angio] = [s.series_id] if ('DIS2D' in (s.image_type[3].strip())): info[DIS2D_TOF_angio] = [s.series_id] From 4f871d9c7669ca30e212c1106bb32f8175e69cbc Mon Sep 17 00:00:00 2001 From: Ali Khan Date: Mon, 18 Nov 2024 11:08:00 -0500 Subject: [PATCH 2/3] fix parsing for more generic StudyID tag in filename --- tar2bids | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tar2bids b/tar2bids index df6cdcf..2bf1755 100755 --- a/tar2bids +++ b/tar2bids @@ -213,13 +213,20 @@ do # x is studyID, for instance 1 if [[ $patient_etc == *_[0-9].*.* ]]; then patient=${patient_etc%_[0-9].*.*} - fi #PI_project_studydate_PatientName_StudyDate_xy.hashcode.tar # StudyDate: for instance, 20190101 # xy is StudyID, for instance, 01 - if [[ $patient_etc == *_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_[0-9][0-9].*.* ]]; then + elif [[ $patient_etc == *_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_[0-9][0-9].*.* ]]; then patient=${patient_etc%_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_[0-9][0-9].*.*} + + #PI_project_studydate_PatientName_StudyID.hashcode.tar + # x is studyID, for instance 1 + else + studyid_etc=`echo $patient_etc | awk -F '_' '{print $NF}'` + patient=${patient_etc%_${studyid_etc}} + echo "studyid_etc: ${studyid_etc}" + echo "patient: ${patient}" fi # if $patient is empty, skip it. From 4fc9830ee74cd02e5de3bbe41ef132ec76a68249 Mon Sep 17 00:00:00 2001 From: Ali Khan Date: Mon, 18 Nov 2024 11:06:30 -0500 Subject: [PATCH 3/3] update to latest dcm2niix use heudiconv fork with unstacked dcm commit This uses the latest heudiconv and cherry-picks the commit from AlanKuurstra: support extended metadata from single unstacked dicom, dimension > 3 --- Dockerfile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 68c257c..7f53247 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,10 +2,11 @@ FROM debian:bullseye LABEL maintainer="" # dcm2niix version -ENV DCM2NIIXTAG v1.0.20230411 +ENV DCM2NIIXTAG v1.0.20240202 #heudiconv version: -ENV HEUDICONVTAG unstacked_dcm +ENV HEUDICONVOWNER akhanf +ENV HEUDICONVTAG v1.3.2+enhdicom.0 #bids validator version: ENV BIDSTAG 1.9.7 @@ -44,7 +45,7 @@ RUN apt-get update -qq \ git \ python3-setuptools \ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ - && git clone https://github.com/AlanKuurstra/heudiconv.git /src/heudiconv \ + && git clone https://github.com/${HEUDICONVOWNER}/heudiconv.git /src/heudiconv \ && git -C /src/heudiconv checkout ${HEUDICONVTAG} WORKDIR /src/heudiconv RUN python3 -m pip install --no-cache-dir -r /src/heudiconv/requirements.txt \