Skip to content

Commit

Permalink
fixed trimming/scaling for weird NIfTI cases (with a weird affine)
Browse files Browse the repository at this point in the history
  • Loading branch information
pjmark committed Aug 2, 2024
1 parent 9cb4b9a commit c52d9a6
Showing 1 changed file with 52 additions and 14 deletions.
66 changes: 52 additions & 14 deletions niftypet/nimpa/prc/prc.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,14 +258,16 @@ def imtrimup(fims, refim='', affine=None, scale=2, divdim=8**2, fmax=0.05, int_o
Cnt = {}

# case when input folder is given
if isinstance(fims, (str, pathlib.PurePath)) and os.path.isdir(fims):
if isinstance(fims, (str, PurePath)) and os.path.isdir(fims):
# list of input images (e.g., PET)
fimlist = [os.path.join(fims, f) for f in os.listdir(fims) if hasext(f, niiext)]
imdic = imio.niisort(fimlist, memlim=memlim)
if not (imdic['N'] > 50 and memlim):
imin = imdic['im']
imshape = imdic['shape']
affine = imdic['affine']
flip = imdic['flip']
trnsp = imdic['transpose']
fldrin = fims
fnms = [os.path.basename(f).split('.nii')[0] for f in imdic['files'] if f is not None]
# number of images/frames
Expand All @@ -274,14 +276,16 @@ def imtrimup(fims, refim='', affine=None, scale=2, divdim=8**2, fmax=0.05, int_o

# case when input file is a 3D or 4D NIfTI image
elif isinstance(fims,
(str, pathlib.PurePath)) and os.path.isfile(fims) and hasext(fims, niiext):
(str, PurePath)) and os.path.isfile(fims) and hasext(fims, niiext):
imdic = imio.getnii(fims, output='all')
imin = imdic['im']
if imin.ndim == 3:
imin.shape = (1, imin.shape[0], imin.shape[1], imin.shape[2])
imdtype = imdic['dtype']
imshape = imdic['shape'][-3:]
affine = imdic['affine']
flip = imdic['flip']
trnsp = imdic['transpose']
fldrin = os.path.dirname(fims)
fnms = imin.shape[0] * [os.path.basename(fims).split('.nii')[0]]
# number of images/frames
Expand All @@ -292,9 +296,11 @@ def imtrimup(fims, refim='', affine=None, scale=2, divdim=8**2, fmax=0.05, int_o
imdic = imio.niisort(fims, memlim=memlim)
if not (imdic['N'] > 50 and memlim):
imin = imdic['im']
imdtype = imdic['dtype']
imshape = imdic['shape']
affine = imdic['affine']
imdtype = imdic['dtype']
flip = imdic['flip']
trnsp = imdic['transpose']
fldrin = os.path.dirname(fims[0])
fnms = [os.path.basename(f).split('.nii')[0] for f in imdic['files']]
# number of images/frames
Expand Down Expand Up @@ -441,15 +447,25 @@ def imtrimup(fims, refim='', affine=None, scale=2, divdim=8**2, fmax=0.05, int_o
IZ = divdim * ((tmp+divdim-1) // divdim)
iz0 -= IZ - tmp + 1

# > this assumes the image 'bottom' is always 'busy' hence equal to the full image extension (shape)

Check failure on line 450 in niftypet/nimpa/prc/prc.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] niftypet/nimpa/prc/prc.py#L450

E501 line too long (104 > 99 characters)
Raw output
niftypet/nimpa/prc/prc.py:450:100: E501 line too long (104 > 99 characters)
iz1 = imsum.shape[0]

# save the trimming parameters in a dic
trimpar = {'x': (ix0, ix1), 'y': (iy0, iy1), 'z': (iz0), 'fmax': fmax, 'scale': scale}

# new dims (z,y,x)
newdims = (imsum.shape[0] - iz0, iy1 - iy0 + 1, ix1 - ix0 + 1)
#>---------------------------------------------------------------

Check failure on line 456 in niftypet/nimpa/prc/prc.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] niftypet/nimpa/prc/prc.py#L456

E265 block comment should start with '# '
Raw output
niftypet/nimpa/prc/prc.py:456:5: E265 block comment should start with '# '
# > NEW DIMENSIONS (z,y,x)

newdims = (iz1 - iz0, iy1 - iy0 + 1, ix1 - ix0 + 1)
imtrim = np.zeros((Nim,) + newdims, dtype=imdtype)
imsumt = np.zeros(newdims, dtype=imdtype)
# in case of needed padding (negative indx resulting above)
# the absolute values are supposed to work like padding in case the indx are negative
#>---------------------------------------------------------------

Check failure on line 462 in niftypet/nimpa/prc/prc.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] niftypet/nimpa/prc/prc.py#L462

E265 block comment should start with '# '
Raw output
niftypet/nimpa/prc/prc.py:462:5: E265 block comment should start with '# '

#>---------------------------------------------------------------

Check failure on line 464 in niftypet/nimpa/prc/prc.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] niftypet/nimpa/prc/prc.py#L464

E265 block comment should start with '# '
Raw output
niftypet/nimpa/prc/prc.py:464:5: E265 block comment should start with '# '
# > PADDING (when needed)
# in case of needed padding (where negative indices are obtained above)
# the absolute values are supposed to work like padding in such a case
#>---------------------------------------------------------------

Check failure on line 468 in niftypet/nimpa/prc/prc.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] niftypet/nimpa/prc/prc.py#L468

E265 block comment should start with '# '
Raw output
niftypet/nimpa/prc/prc.py:468:5: E265 block comment should start with '# '
iz0s, iy0s, ix0s = iz0, iy0, ix0
iz0t, iy0t, ix0t = 0, 0, 0
if iz0 < 0:
Expand Down Expand Up @@ -491,18 +507,36 @@ def imtrimup(fims, refim='', affine=None, scale=2, divdim=8**2, fmax=0.05, int_o

# first trim the sum image
imsumt[iz0t:, iy0t:iy1t, ix0t:ix1t] = imsum[iz0s:, iy0s:iy1 + 1, ix0s:ix1 + 1]
#>---------------------------------------------------------------

Check failure on line 510 in niftypet/nimpa/prc/prc.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] niftypet/nimpa/prc/prc.py#L510

E265 block comment should start with '# '
Raw output
niftypet/nimpa/prc/prc.py:510:5: E265 block comment should start with '# '

# > new affine matrix for the upscaled and trimmed image
# > use the scale factor reversely for consistency
A = np.diag(np.append(sf[::-1], 1.) * np.diag(affine))

# > note half of new voxel offset is used for the new centre of voxels
A[0, 3] = affine[0, 3] + A[0, 0] * (ix0 - 0.5 * (scale[2] - 1))
A[1, 3] = affine[1, 3] + (affine[1, 1] * (imshape[1] - 1) - A[1, 1] * (iy1 - 0.5 *
(scale[1] - 1)))
A[2, 3] = affine[2, 3] - A[2, 2] * 0.5 * (scale[0] - 1)
if flip[0]<0: # < this is `x` (note flip array is oriented differently to shape/scale)

Check failure on line 517 in niftypet/nimpa/prc/prc.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] niftypet/nimpa/prc/prc.py#L517

E225 missing whitespace around operator
Raw output
niftypet/nimpa/prc/prc.py:517:15: E225 missing whitespace around operator
A[0, 3] = affine[0, 3] + A[0, 0] * (ix0 - (scale[2]-1)/2)
else:
# not tested - needs to be checked on an appropriate example
A[0, 3] = affine[0, 3] + affine[0, 0]*(imshape[2]-1) - A[0, 0]*(ix1 - (scale[2]-1)/2)

Check failure on line 522 in niftypet/nimpa/prc/prc.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] niftypet/nimpa/prc/prc.py#L522

W293 blank line contains whitespace
Raw output
niftypet/nimpa/prc/prc.py:522:1: W293 blank line contains whitespace
if flip[1]>0:

Check failure on line 523 in niftypet/nimpa/prc/prc.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] niftypet/nimpa/prc/prc.py#L523

E225 missing whitespace around operator
Raw output
niftypet/nimpa/prc/prc.py:523:15: E225 missing whitespace around operator
A[1, 3] = affine[1, 3] + affine[1, 1]*(imshape[1]-1) - A[1, 1]*(iy1 - (scale[1]-1)/2)
else:
A[1, 3] = affine[1, 3] + A[1, 1]*(iy0 - (scale[1]-1)/2)

if flip[2]>0:

Check failure on line 528 in niftypet/nimpa/prc/prc.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] niftypet/nimpa/prc/prc.py#L528

E225 missing whitespace around operator
Raw output
niftypet/nimpa/prc/prc.py:528:15: E225 missing whitespace around operator
A[2, 3] = affine[2, 3] - A[2, 2]*(scale[0]-1)/2
else:
A[2, 3] = affine[2, 3] + A[2, 2]*(iz0 - (scale[0]-1)/2)

A[3, 3] = 1

# A[0, 3] = affine[0, 3] + A[0, 0] * (ix0 - 0.5 * (scale[2] - 1))
# A[1, 3] = affine[1, 3] + (affine[1, 1] * (imshape[1] - 1) - A[1, 1] * (iy1 - 0.5 * (scale[1] - 1)))

Check failure on line 536 in niftypet/nimpa/prc/prc.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] niftypet/nimpa/prc/prc.py#L536

E501 line too long (105 > 99 characters)
Raw output
niftypet/nimpa/prc/prc.py:536:100: E501 line too long (105 > 99 characters)
# A[2, 3] = affine[2, 3] - A[2, 2] * 0.5 * (scale[0] - 1)
# A[3, 3] = 1

# output dictionary
dctout = {'affine': A, 'trimpar': trimpar, 'imsum': imsumt}

Expand All @@ -518,7 +552,11 @@ def imtrimup(fims, refim='', affine=None, scale=2, divdim=8**2, fmax=0.05, int_o
fsum = os.path.join(
petudir,
fcomment_pfx + 'avg_trimmed-upsampled-scale-' + scale_fnm + fcomment + '.nii.gz')
imio.array2nii(imsumt[::-1, ::-1, :], A, fsum, descrip=niidescr)
imio.array2nii(
imsumt, A, fsum,
descrip=niidescr,
flip=flip,
trnsp=trnsp)
log.debug('saved averaged image to: {}'.format(fsum))
dctout['fsum'] = fsum

Expand Down Expand Up @@ -549,7 +587,7 @@ def imtrimup(fims, refim='', affine=None, scale=2, divdim=8**2, fmax=0.05, int_o
_frm = '_trmfrm' + str(i)
_fstr = '_trimmed-upsampled-scale-' + scale_fnm + _frm * (Nim > 1) + fcomment
fpetu.append(os.path.join(petudir, fnms[i] + _fstr + '_i.nii.gz'))
imio.array2nii(imtrim[i, ::-1, ::-1, :], A, fpetu[i], descrip=niidescr)
imio.array2nii(imtrim[i,...], A, fpetu[i], descrip=niidescr, flip=flip, trnsp=trnsp) #[i,::-1,::-1,:]

Check failure on line 590 in niftypet/nimpa/prc/prc.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] niftypet/nimpa/prc/prc.py#L590

E231 missing whitespace after ','
Raw output
niftypet/nimpa/prc/prc.py:590:40: E231 missing whitespace after ','

Check failure on line 590 in niftypet/nimpa/prc/prc.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] niftypet/nimpa/prc/prc.py#L590

E501 line too long (117 > 99 characters)
Raw output
niftypet/nimpa/prc/prc.py:590:100: E501 line too long (117 > 99 characters)

Check failure on line 590 in niftypet/nimpa/prc/prc.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] niftypet/nimpa/prc/prc.py#L590

E262 inline comment should start with '# '
Raw output
niftypet/nimpa/prc/prc.py:590:102: E262 inline comment should start with '# '
log.debug('saved upsampled PET image to: {}'.format(fpetu[i]))

if store_img:
Expand All @@ -558,7 +596,7 @@ def imtrimup(fims, refim='', affine=None, scale=2, divdim=8**2, fmax=0.05, int_o
scale_fnm) + _nfrm * (Nim > 1) + fcomment + '.nii.gz'
log.info('storing image to:\n{}'.format(fim))

imio.array2nii(np.squeeze(imtrim[:, ::-1, ::-1, :]), A, fim, descrip=niidescr)
imio.array2nii(np.squeeze(imtrim), A, fim, descrip=niidescr, flip=flip, trnsp=trnsp) #[:, ::-1, ::-1, :]

Check failure on line 599 in niftypet/nimpa/prc/prc.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] niftypet/nimpa/prc/prc.py#L599

E262 inline comment should start with '# '
Raw output
niftypet/nimpa/prc/prc.py:599:94: E262 inline comment should start with '# '

Check failure on line 599 in niftypet/nimpa/prc/prc.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] niftypet/nimpa/prc/prc.py#L599

E501 line too long (112 > 99 characters)
Raw output
niftypet/nimpa/prc/prc.py:599:100: E501 line too long (112 > 99 characters)
dctout['fim'] = fim

# file names (with paths) for the intermediate PET images
Expand Down

0 comments on commit c52d9a6

Please sign in to comment.