Skip to content

Commit 1a8e675

Browse files
Merge pull request #30 from AdebayoBraimah/dev5
Dev5
2 parents 717aca6 + cd96029 commit 1a8e675

11 files changed

Lines changed: 98 additions & 18 deletions

File tree

CHANGES.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
CHANGES
22
=========
33

4+
v0.1.1
5+
---------
6+
7+
* BUG FIX: Fixed issue for incorrect references to tmp directories. This caused image conversion exceptions to be thrown, and thus no NIFTI BIDS files would be returned.
8+
* BUG FIX: Fixed issue for cases in which hidden indexing files (._) would be included in the file search.
9+
410
v0.1.0
511
---------
612

713
* BUG FIX: Fixed bug in setup, which prevented proper installation and usage of the ``study_proc`` executable.
8-
* UPDATE: The documentation is now `available <https://convert-source.readthedocs.io/en/master/>`_.
14+
* UPDATE: The documentation is now `available <https://convert-source.readthedocs.io/en/0.1.0/>`_.
915

1016
v0.1.rc1
1117
---------

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[![CircleCI](https://circleci.com/gh/AdebayoBraimah/convert_source.svg?style=svg)](https://app.circleci.com/pipelines/github/AdebayoBraimah/convert_source) [![Documentation Status](https://readthedocs.org/projects/convert-source/badge/?version=latest)](https://convert-source.readthedocs.io/en/master/)
1+
[![CircleCI](https://circleci.com/gh/AdebayoBraimah/convert_source.svg?style=svg)](https://app.circleci.com/pipelines/github/AdebayoBraimah/convert_source) [![Documentation Status](https://readthedocs.org/projects/convert-source/badge/?version=latest)](https://convert-source.readthedocs.io/en/latest/)
22

33
# convert_source
44
Convert source `DICOM`, `PAR REC` or `NIFTI` image data to BIDS directory layout.

convert_source/batch_convert.py

Lines changed: 72 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -111,17 +111,21 @@ def batch_proc(study_img_dir: str,
111111
* Corresponding list of bval files.
112112
* Corresponding list of bvec files.
113113
'''
114+
study_img_dir: str = os.path.abspath(study_img_dir)
115+
114116
# Check dependencies
115117
dcm2niix_cmd: Command = Command("dcm2niix")
116118
dcm2niix_cmd.check_dependency(path_envs=path_envs)
117119

118120
# Write logs
119121
misc_dir: str = os.path.join(out_dir,'.misc')
120122
if os.path.exists(misc_dir):
123+
out_dir: str = os.path.abspath(out_dir)
121124
misc_dir: str = os.path.abspath(misc_dir)
122125
else:
123126
os.makedirs(misc_dir)
124127
misc_dir: str = os.path.abspath(misc_dir)
128+
out_dir: str = os.path.abspath(out_dir)
125129

126130
now = datetime.now()
127131
dt_string: str = str(now.strftime("%m_%d_%Y_%H_%M"))
@@ -786,7 +790,7 @@ def source_to_bids(sub_data: SubDataInfo,
786790
# Using TmpDir and TmpFile context managers
787791
with TmpDir(tmp_dir=sub_tmp,use_cwd=False) as tmp:
788792
with TmpDir.TmpFile(tmp_dir=tmp.tmp_dir) as f:
789-
_ = tmp.mk_tmp_dir()
793+
tmp.mk_tmp_dir()
790794
[_path, basename, _ext] = f.file_parts()
791795
try:
792796
img_data = convert_image_data(file=data,
@@ -904,7 +908,7 @@ def source_to_bids(sub_data: SubDataInfo,
904908
append_dwi_info=append_dwi_info,
905909
zero_pad=zero_pad,
906910
cprss_lvl=cprss_lvl)
907-
_ = tmp.rm_tmp_dir()
911+
tmp.rm_tmp_dir()
908912
return (imgs,
909913
jsons,
910914
bvals,
@@ -929,7 +933,7 @@ def source_to_bids(sub_data: SubDataInfo,
929933
append_dwi_info=append_dwi_info,
930934
zero_pad=zero_pad,
931935
cprss_lvl=cprss_lvl)
932-
_ = tmp.rm_tmp_dir()
936+
tmp.rm_tmp_dir()
933937
return (imgs,
934938
jsons,
935939
bvals,
@@ -991,13 +995,13 @@ def source_to_bids(sub_data: SubDataInfo,
991995
else:
992996
bvecs.append("")
993997
# Clean-up
994-
_ = tmp.rm_tmp_dir()
998+
tmp.rm_tmp_dir()
995999
return (imgs,
9961000
jsons,
9971001
bvals,
9981002
bvecs)
9991003
except ConversionError:
1000-
_ = tmp.rm_tmp_dir()
1004+
tmp.rm_tmp_dir()
10011005
return [""],[""],[""],[""]
10021006

10031007
def nifti_to_bids(sub_data: SubDataInfo,
@@ -1075,7 +1079,7 @@ def nifti_to_bids(sub_data: SubDataInfo,
10751079

10761080
# Use TmpDir and NiiFile class context managers
10771081
with TmpDir(tmp_dir=sub_tmp, use_cwd=False) as tmp:
1078-
_ = tmp.mk_tmp_dir()
1082+
tmp.mk_tmp_dir()
10791083
with NiiFile(data) as n:
10801084
[path, basename, ext] = n.file_parts()
10811085
img_files: List[str] = glob.glob(os.path.join(path,basename + "*" + ext))
@@ -1270,7 +1274,7 @@ def nifti_to_bids(sub_data: SubDataInfo,
12701274
bvals.append("")
12711275
bvecs.append("")
12721276
# Clean-up
1273-
_ = tmp.rm_tmp_dir()
1277+
tmp.rm_tmp_dir()
12741278

12751279
return (imgs,
12761280
jsons,
@@ -1401,7 +1405,7 @@ def bids_ignore(out_dir: str) -> str:
14011405

14021406
# Write to file using File class context manager
14031407
with File(new_file) as f:
1404-
f.write_txt(".misc \n")
1408+
f.write_txt(".misc/* \n")
14051409
f.write_txt("unknown/* \n")
14061410

14071411
return new_file
@@ -1426,9 +1430,68 @@ def log_file(log: str) -> LogFile:
14261430
log: LogFile = LogFile(log_file=log)
14271431

14281432
now = datetime.now()
1429-
dt_string = now.strftime("%A %B %d, %Y %H:%M%:%S")
1433+
dt_string = now.strftime("%A %B %d, %Y %H:%M:%S")
14301434

14311435
log.info(dt_string)
14321436
log.info(f"convert_source v{__version__}")
14331437

14341438
return log
1439+
1440+
# This function was added for the Mac OS X case in which hidden
1441+
# temporary indexing files are present throughout a given directory.
1442+
#
1443+
# This function was designed to handle that use case, however:
1444+
#
1445+
# * Implementation methods are currently unclear
1446+
# * This approach is VERY SLOW as each parent directory is recursively searched.
1447+
#
1448+
# Moreover, this should be included in a later release should this continue to be an
1449+
# issue moving forward.
1450+
#
1451+
# Adebayo Braimah - 12 March 2021
1452+
#
1453+
# def dir_clean_up(directory: str) -> str:
1454+
# '''Removes temporary indexing files (commonly found on
1455+
# Mac OS X).
1456+
#
1457+
# These files are generally problematic as they cause several of
1458+
# ``convert_source``'s core functions to behave unpredictably.
1459+
#
1460+
# Any identified tempoary indexing files are removed.
1461+
#
1462+
# NOTE: The implementation here does work, but is VERY SLOW as the number of
1463+
# files and directories is assumed to be large.
1464+
#
1465+
# Usage example:
1466+
# >>> directory = dir_clean_up(directory)
1467+
# >>>
1468+
#
1469+
# Arguments:
1470+
# directory: Input parent directory to recursively search (for hidden files in).
1471+
#
1472+
# Returns:
1473+
# Absolute path to directory as a string.
1474+
# '''
1475+
# from shutil import rmtree
1476+
#
1477+
# if os.path.exists(directory):
1478+
# directory = os.path.abspath(directory)
1479+
# else:
1480+
# raise FileNotFoundError("Input directory does not appear to exist.")
1481+
#
1482+
# # This works - but is slow | O(n) space and time
1483+
# for root,dirnames,filenames in os.walk(directory):
1484+
# if len(dirnames) > 0:
1485+
# for dirname in dirnames:
1486+
# if '._' in dirname:
1487+
# hd_name: str = os.path.join(root,dirname)
1488+
# rmtree(hd_name)
1489+
# print(hd_name)
1490+
# if len(filenames) > 0:
1491+
# for file in filenames:
1492+
# if '._' in file:
1493+
# hf_name: str = os.path.join(root,file)
1494+
# # hf_list.append(hf_name)
1495+
# os.remove(hf_name)
1496+
# print(hf_name)
1497+
# return directory

convert_source/cs_utils/fileio.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,8 @@ def file_parts(self,
185185
file = self.abs_path()
186186

187187
if platform.system().lower() == "windows":
188-
[path, _filename] = os.path.splitdrive(file)
188+
# [path, _filename] = os.path.splitdrive(file)
189+
[path, _filename] = os.path.split(file)
189190
else:
190191
[path, _filename] = os.path.split(file)
191192

@@ -359,7 +360,7 @@ def __init__(self,
359360
self.tmp_file: str = tmp_file
360361
else:
361362
_n: int = 10000 # maximum N for random number generator
362-
self.tmp_file: str = "tmp_file_" + str(random.randint(0,_n))
363+
self.tmp_file: str = "tmp_file_" + str(random.randint(0,_n)) + ".txt"
363364

364365
if ext:
365366
self.tmp_file: str = self.tmp_file + f".{ext}"

convert_source/cs_utils/img_dir.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ def img_dir_list(directory: str,
8282
for root,dirnames,filenames in os.walk(directory):
8383
if len(filenames) > 0:
8484
for file in filenames:
85+
if '._' in file:
86+
# Skip hidden files if they exist.
87+
continue
8588
if '.dcm' in file.lower() or '.PAR' in file.upper() or '.nii' in file.lower():
8689
file_name = os.path.join(root,file)
8790
if '.dcm' in file.lower():

convert_source/cs_utils/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,7 @@ def convert_image_data(file: str,
847847
# Create TmpDir object
848848
with TmpDir(tmp_dir=out_dir,use_cwd=False) as tmp_dir:
849849
# Create temporary output directory
850-
_ = tmp_dir.mk_tmp_dir()
850+
tmp_dir.mk_tmp_dir()
851851

852852
# Output directory
853853
out_dir: str = os.path.abspath(out_dir)
@@ -866,7 +866,7 @@ def convert_image_data(file: str,
866866
[imgs, jsons, bvals, bvecs] = img_data.copy_img_data(target_dir=out_dir)
867867

868868
# Clean-up
869-
_ = tmp_dir.rm_tmp_dir(rm_parent=False)
869+
tmp_dir.rm_tmp_dir(rm_parent=False)
870870

871871
# Image file check
872872
if len(imgs) == 0:

convert_source/imgio/pario.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ def get_echo_time(par_file: str,
178178
df: pd.DataFrame = df.dropna(axis=0)
179179

180180
with TmpDir(tmp_dir=tmp_dir,use_cwd=False) as tmp:
181-
_ = tmp.mk_tmp_dir()
181+
tmp.mk_tmp_dir()
182182
with TmpDir.TmpFile(tmp_dir=tmp.tmp_dir,ext="txt") as f:
183183
df.to_csv(f.file,sep=",",header=False,index=False)
184184
mat = np.loadtxt(f.file,delimiter=",")
@@ -222,7 +222,7 @@ def get_flip_angle(par_file: str,
222222
df: pd.DataFrame = df.dropna(axis=0)
223223

224224
with TmpDir(tmp_dir=tmp_dir,use_cwd=False) as tmp:
225-
_ = tmp.mk_tmp_dir()
225+
tmp.mk_tmp_dir()
226226
with TmpDir.TmpFile(tmp_file="file.tmp.txt",tmp_dir=tmp.tmp_dir) as f:
227227
df.to_csv(f.file,sep=",",header=False,index=False)
228228
mat = np.loadtxt(f.file,delimiter=",")

convert_source/tests/01_fileio_test.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def test_file_class():
3030
assert f.file == 'test.file.txt'
3131

3232
def test_command_class():
33+
"""NOTE: This test will FAIL on Windows operating systems."""
3334
x: str = 'ls'
3435
c = Command(x)
3536
c.cmd_list.append(os.getcwd())
@@ -44,7 +45,7 @@ def test_command_class():
4445
def test_tmpdir_class():
4546
x: str = 'tmpdir'
4647
with TmpDir(x,True) as tmp:
47-
_ = tmp.mk_tmp_dir()
48+
tmp.mk_tmp_dir()
4849
assert os.path.exists(tmp.tmp_dir) == True
4950
with TmpDir.TmpFile(tmp.tmp_dir) as f:
5051
f.touch()

convert_source/tests/04_convert_image_test.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ class PlatformInferError(Exception):
8989
assert os.path.exists(file_name) == False
9090

9191
def test_dependency():
92+
"""NOTE: This test will FAIL if ``dcm2niix`` is already in the
93+
system path.
94+
"""
9295
dcm2niix_cmd: Command = Command("dcm2niix")
9396

9497
with pytest.raises(DependencyError):
@@ -130,6 +133,7 @@ def test_data_conversion():
130133
[img, json, bval, bvec] = convert_image_data(data,'test_img',os.getcwd())
131134

132135
def test_cleanup():
136+
"""NOTE: This test currently FAILS on Windows operating systems."""
133137
del_method: bool = False
134138
rm_method: bool = False
135139
rm_item_method: bool = False

convert_source/tests/07_dcmio_test.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ def test_get_mb():
127127
assert get_mb(data) == 1
128128

129129
def test_cleanup():
130+
"""NOTE: This test currently FAILS on Windows operating systems."""
130131
del_method: bool = False
131132
rm_method: bool = False
132133
rm_item_method: bool = False

0 commit comments

Comments
 (0)