diff --git a/niftypet/nimpa/prc/imio.py b/niftypet/nimpa/prc/imio.py index 0ba0854c..322c25ea 100644 --- a/niftypet/nimpa/prc/imio.py +++ b/niftypet/nimpa/prc/imio.py @@ -1,6 +1,5 @@ """image input/output functionalities.""" import datetime -import glob import logging import os import pathlib @@ -79,7 +78,7 @@ def getnii(fim, nan_replace=None, output='image'): # > get orientations from the affine ornt = nib.io_orientation(nim.affine) - trnsp = tuple(np.int8([ornt[2, 0],ornt[1, 0],ornt[0, 0]])) + trnsp = tuple(np.int8([ornt[2, 0], ornt[1, 0], ornt[0, 0]])) flip = tuple(np.int8(ornt[:, 1])) # > voxel size @@ -252,29 +251,20 @@ def nii_gzip(imfile, outpath=''): def pick_t1w(mri): '''Pick the MR T1w from the dictionary for MR->PET registration.''' - - if isinstance(mri, dict): - # check if NIfTI file is given - if 'T1N4' in mri and os.path.isfile(mri['T1N4']): - ft1w = mri['T1N4'] - # or another bias corrected - elif 'T1bc' in mri and os.path.isfile(mri['T1bc']): - ft1w = mri['T1bc'] - elif 'T1nii' in mri and os.path.isfile(mri['T1nii']): - ft1w = mri['T1nii'] - elif 'T1DCM' in mri and os.path.exists(mri['MRT1W']): - # create file name for the converted NIfTI image - fnii = 'converted' - run([rs.DCM2NIIX, '-f', fnii, mri['T1nii']]) - ft1nii = glob.glob(os.path.join(mri['T1nii'], '*converted*.nii*')) - ft1w = ft1nii[0] - else: - raise IOError('could not find a T1w image!') - - else: + if not isinstance(mri, dict): raise IOError('incorrect input given for the T1w image') - return ft1w + # check if NIfTI file is given + if 'T1N4' in mri and os.path.isfile(mri['T1N4']): + return mri['T1N4'] + # or another bias corrected + elif 'T1bc' in mri and os.path.isfile(mri['T1bc']): + return mri['T1bc'] + elif 'T1nii' in mri and os.path.isfile(mri['T1nii']): + return mri['T1nii'] + elif 'T1DCM' in mri and os.path.exists(mri['MRT1W']): + return dcm2nii(mri['T1nii'], 'converted') + raise IOError('could not find a T1w image!') # ====================================================================== @@ -921,59 +911,51 @@ def dcm2nii( fcomment='', outpath='', timestamp=True, - executable='', + executable=None, force=False, ): - ''' - Convert DICOM files in folder (indicated by ) using DCM2NIIX - third-party software. - ''' + """ + Convert DICOM folder `dcmpth` to NIfTI using `dcm2niix` third-party software. + Args: + dcmpth: directory containing DICOM files + """ # skip conversion if the output already exists and not force is selected if os.path.isfile(fimout) and not force: return fimout - if executable == '': - try: - executable = rs.DCM2NIIX - except AttributeError: - raise AttributeError('e> could not find variable DCM2NIIX in resources.py') - elif not os.path.isfile(executable): - raise IOError('e> the executable is incorrect!') + if not executable: + executable = getattr(rs, 'DCM2NIIX', None) + if not executable: + import dcm2niix + executable = dcm2niix.bin + if not os.path.isfile(executable): + raise IOError(f"executable not found:{executable}") if not os.path.isdir(dcmpth): - raise IOError('e> the provided DICOM path is not a folder!') + raise IOError("the provided `dcmpth` is not a folder") - # > output path - if outpath == '' and fimout != '' and '/' in fimout: + # output path + if not outpath and fimout and '/' in fimout: opth = os.path.dirname(fimout) - if opth == '': - opth = dcmpth + opth = opth or dcmpth fimout = os.path.basename(fimout) - - elif outpath == '': - opth = dcmpth - else: - opth = outpath + opth = outpath or dcmpth create_dir(opth) - if fimout == '': + if not fimout: fimout = fprefix if timestamp: fimout += time_stamp(simple_ascii=True) - fimout = fimout.split('.nii')[0] - # convert the DICOM mu-map images to nii run([executable, '-f', fimout, '-o', opth, dcmpth]) - - fniiout = glob.glob(os.path.join(opth, '*' + fimout + '*.nii*')) + fniiout = list(pathlib.Path(opth).glob(f"*{fimout}*.nii*")) if fniiout: - return fniiout[0] - else: - raise ValueError('e> could not get the output file!') + return str(fniiout[0]) + raise ValueError("could not find output nii file") def dcm2im(fpth): diff --git a/niftypet/nimpa/prc/prc.py b/niftypet/nimpa/prc/prc.py index e2f7c3be..da931cd0 100644 --- a/niftypet/nimpa/prc/prc.py +++ b/niftypet/nimpa/prc/prc.py @@ -8,7 +8,6 @@ import pathlib import re import sys -from glob import glob from subprocess import run from textwrap import dedent from warnings import warn @@ -908,15 +907,8 @@ def centre_mass_img(img, output='mm'): # ============================================================================== -def centre_mass_corr( - img, - Cnt=None, - com=None, - flip=None, - outpath=None, - fcomment='_com-modified', - fout=None): - +def centre_mass_corr(img, Cnt=None, com=None, flip=None, outpath=None, fcomment='_com-modified', + fout=None): """ Image centre of mass correction. The O point is in the middle of the image centre of voxel value mass (e.g, radio-activity). @@ -935,7 +927,7 @@ def centre_mass_corr( else: raise ValueError('unrecognised input image') - #------------------------------------------------------------------ + # ------------------------------------------------------------------ # [optional] # > applies if requested a radical correction of orientation by flipping if flip is not None: @@ -944,8 +936,7 @@ def centre_mass_corr( imdct['im'] = imdct['im'][:, ::flip[0], ::flip[1], ::flip[2]] elif dimno == 3: imdct['im'] = imdct['im'][::flip[0], ::flip[1], ::flip[2]] - #------------------------------------------------------------------ - + # ------------------------------------------------------------------ # > check if the dictionary of constants is given if Cnt is None: @@ -1024,7 +1015,7 @@ def centre_mass_corr( # get a new NIfTI image for the perturbed MR imdata = innii.get_fdata() if flip is not None: - imdata = imdata[::flip[2],::flip[1],::flip[0],...] + imdata = imdata[::flip[2], ::flip[1], ::flip[0], ...] newnii = nib.Nifti1Image(imdata, mA, innii.header) fnew = os.path.join(opth, fnm) @@ -1308,7 +1299,7 @@ def bias_field_correction(fmr, fimout='', outpath='', fcomment='_N4bias', execut outdct.setdefault('fim', []) outdct['fim'].append(fn4) - if len(outdct['fim'])==1: + if len(outdct['fim']) == 1: outdct['fim'] = outdct['fim'][0] return outdct @@ -1384,11 +1375,7 @@ def mr2pet_rigid(fpet, mridct, Cnt, outpath='', fcomment='', rmsk=True, rfwhm=15 elif 'T1bc' in mridct and os.path.isfile(mridct['T1bc']): ft1w = mridct['T1bc'] elif 'T1DCM' in mridct and os.path.exists(mridct['MRT1W']): - # create file name for the converted NIfTI image - fnii = 'converted' - run([Cnt['DCM2NIIX'], '-f', fnii, mridct['T1nii']]) - ft1nii = glob(os.path.join(mridct['T1nii'], '*converted*.nii*')) - ft1w = ft1nii[0] + ft1w = imio.dcm2nii(mridct['T1nii'], 'converted', executable=Cnt.get('DCM2NIIX', None)) else: raise ValueError('disaster: no T1w image!') diff --git a/setup.cfg b/setup.cfg index fe2f3da0..046ad023 100644 --- a/setup.cfg +++ b/setup.cfg @@ -47,6 +47,7 @@ setup_requires= miutil[cuda]>=0.4.0 install_requires= cuvec>=2.3.1 + pydcm2niix>=1.0.20220116 dipy>=1.3.0 miutil[nii]>=0.4.2 nibabel>=2.4.0 diff --git a/setup.py b/setup.py index 2fa72c34..d8af94a4 100755 --- a/setup.py +++ b/setup.py @@ -51,25 +51,12 @@ # get the current setup, if any Cnt = resources.get_setup() # check the installation of tools -chck_tls = tls.check_version(Cnt, chcklst=["RESPATH", "REGPATH", "DCM2NIIX"]) +chck_tls = tls.check_version(Cnt, chcklst=["RESPATH", "REGPATH"]) # ------------------------------------------- # NiftyPET tools: # ------------------------------------------- if "sdist" not in sys.argv or any(i in sys.argv for i in ["build", "bdist", "wheel"]): - # DCM2NIIX - if not chck_tls["DCM2NIIX"]: - # reply = tls.query_yesno("q> dcm2niix not found.\n Install it?") - # if reply: - log.info( - dedent("""\ - -------------------------------------------------------------- - Installing dcm2niix ... - --------------------------------------------------------------""")) - Cnt = tls.install_tool("dcm2niix", Cnt) - # --------------------------------------- - - # ------------------------------------------- # NiftyReg if not chck_tls["REGPATH"] or not chck_tls["RESPATH"]: reply = True