Skip to content
Open
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
15 changes: 11 additions & 4 deletions pydeface/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,15 @@ def output_checks(infile, outfile=None, force=False):


def generate_tmpfiles(verbose=True):
_, template_reg_mat = tempfile.mkstemp(suffix='.mat')
_, warped_mask = tempfile.mkstemp(suffix='.nii.gz')
paths = []
for suffix in ('.mat', '.nii.gz', '.nii.gz', '.mat'):
fd, path = tempfile.mkstemp(suffix=suffix)
# only the names are needed; FSL opens the files itself
os.close(fd)
paths.append(path)
template_reg_mat, warped_mask, template_reg, warped_mask_mat = paths
if verbose:
print(f'Temporary files:\n {template_reg_mat}\n {warped_mask}')
_, template_reg = tempfile.mkstemp(suffix='.nii.gz')
_, warped_mask_mat = tempfile.mkstemp(suffix='.mat')
return template_reg, template_reg_mat, warped_mask, warped_mask_mat


Expand Down Expand Up @@ -121,6 +124,10 @@ def deface_image(
flirt.inputs.out_matrix_file = warped_mask_mat
flirt.run()

# this matrix is not returned to the caller, so nobody else can remove it
if os.path.exists(warped_mask_mat):
os.remove(warped_mask_mat)

# multiply mask by infile and save
infile_img = load(infile)
infile_data = np.asarray(infile_img.dataobj)
Expand Down
33 changes: 33 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,39 @@ def test_generate_tmpfiles():
os.remove(f)


def test_generate_tmpfiles_closes_descriptors():
fd_dir = Path('/proc/self/fd')
if not fd_dir.exists():
pytest.skip('needs /proc/self/fd')
before = len(os.listdir(fd_dir))
for _ in range(5):
pdu.cleanup_files(*pdu.generate_tmpfiles(verbose=False))
assert len(os.listdir(fd_dir)) == before


def test_deface_image_leaves_no_matrix_file(monkeypatch, tmp_path):
import nibabel as nib
import numpy as np
from nipype.interfaces import fsl

def fake_run(self):
img = nib.Nifti1Image(np.ones((4, 4, 4), dtype='f4'), np.eye(4))
nib.save(img, self.inputs.out_file)

infile = tmp_path / 'in.nii.gz'
nib.save(nib.Nifti1Image(np.ones((4, 4, 4), dtype='f4'), np.eye(4)), infile)
tmp_dir = tmp_path / 'tmp'
tmp_dir.mkdir()
monkeypatch.setattr('tempfile.tempdir', str(tmp_dir))
monkeypatch.setattr(pdu.shutil, 'which', lambda name: '/fsl/bin/flirt')
monkeypatch.setenv('FSLDIR', '/fsl')
monkeypatch.setattr(fsl.FLIRT, 'run', fake_run)

pdu.deface_image(str(infile), force=True, forcecleanup=True, verbose=False)

assert list(tmp_dir.iterdir()) == []


def test_get_outfile_type():
assert pdu.get_outfile_type('path.nii.gz') == 'NIFTI_GZ'
assert pdu.get_outfile_type('path.nii') == 'NIFTI'
Expand Down