Repository: yeatmanlab/pyAFQ
Pull request #827 (2022-05-11 19:28:46)

[FIX] Replace split(.) with splitext()
Once this is merged, we should consider a minor release as this is needed to work with QSIprep

arokem: Could you please rebase this on top of the now-merged #826? 
pep8speaks: Hello @36000! Thanks for updating this PR. We checked the lines you've touched for [PEP 8](https://www.python.org/dev/peps/pep-0008) issues, and found:















* In the file [`AFQ/utils/tests/test_path.py`](https://github.com/yeatmanlab/pyAFQ/blob/2179b15f866d7bbff4b2addec86307ef2943a77f/AFQ/utils/tests/test_path.py):

> [Line 3:1](https://github.com/yeatmanlab/pyAFQ/blob/2179b15f866d7bbff4b2addec86307ef2943a77f/AFQ/utils/tests/test_path.py#L3): [E302](https://duckduckgo.com/?q=pep8%20E302) expected 2 blank lines, found 1



Patch:
diff --git a/AFQ/data/fetch.py b/AFQ/data/fetch.py
index 481e6e72..8dd05f70 100644
--- a/AFQ/data/fetch.py
+++ b/AFQ/data/fetch.py
@@ -6,6 +6,7 @@ from dipy.io.streamline import (
     load_tractogram, save_tractogram, StatefulTractogram, Space)
 from dipy.data.fetcher import _make_fetcher
 import dipy.data as dpd
+from AFQ.utils.path import drop_extension
 
 import os
 import os.path as op
@@ -93,7 +94,7 @@ def _fetcher_to_template(fetcher, as_img=False, resample_to=False):
                                            img.affine,
                                            resample_to.affine).get_fdata(),
                                   resample_to.affine)
-        template_dict[f.split('.')[0]] = img
+        template_dict[drop_extension(f)] = img
     return template_dict
 
 
@@ -929,8 +930,8 @@ def read_hcp_atlas(n_bundles=16, as_file=False):
         "centroid")
     os.makedirs(centroid_folder, exist_ok=True)
     for bundle_file in bundle_files:
-        bundle = op.splitext(op.split(bundle_file)[-1])[0]
-        centroid_file = op.join(centroid_folder, bundle + ".trk")
+        bundle = drop_extension(op.split(bundle_file)[-1])
+        centroid_file = op.join(centroid_folder, f"{bundle}.trk")
         bundle_dict[bundle] = {}
         if not op.exists(centroid_file):
             bundle_sl = load_tractogram(
diff --git a/AFQ/definitions/utils.py b/AFQ/definitions/utils.py
index 124c4956..08c278ea 100644
--- a/AFQ/definitions/utils.py
+++ b/AFQ/definitions/utils.py
@@ -1,5 +1,7 @@
 import os.path as op
 
+from AFQ.utils.path import drop_extension
+
 __all__ = ["Definition", "find_file", "name_from_path"]
 
 
@@ -63,7 +65,7 @@ def _arglist_to_string(args, get_attr=None):
 
 def name_from_path(path):
     file_name = op.basename(path)  # get file name
-    file_name = op.splitext(file_name)[0]  # remove extension
+    file_name = drop_extension(file_name)  # remove extension
     if "-" in file_name:
         file_name = file_name.split("-")[-1]  # get suffix if exists
     return file_name
diff --git a/AFQ/tasks/decorators.py b/AFQ/tasks/decorators.py
index 41dce61a..34a23842 100644
--- a/AFQ/tasks/decorators.py
+++ b/AFQ/tasks/decorators.py
@@ -12,6 +12,7 @@ from AFQ.data.s3bids import write_json
 import numpy as np
 
 from AFQ.tasks.utils import get_fname
+from AFQ.utils.path import drop_extension
 
 
 __all__ = ["as_file", "as_model", "as_dt_deriv", "as_img"]
@@ -104,7 +105,7 @@ def as_file(suffix, include_track=False, include_seg=False):
                 else:
                     img_trk_or_csv.to_csv(this_file)
                 meta_fname = get_fname(
-                    subses_dict, suffix.split('.')[0] + '.json',
+                    subses_dict, drop_extension(suffix) + '.json',
                     tracking_params=tracking_params,
                     segmentation_params=segmentation_params)
                 write_json(meta_fname, meta)
diff --git a/AFQ/tasks/mapping.py b/AFQ/tasks/mapping.py
index 888e9a4e..2801e238 100644
--- a/AFQ/tasks/mapping.py
+++ b/AFQ/tasks/mapping.py
@@ -9,6 +9,7 @@ from AFQ.tasks.decorators import as_file
 from AFQ.tasks.utils import get_fname, with_name
 import AFQ.data.fetch as afd
 from AFQ.data.s3bids import write_json
+from AFQ.utils.path import drop_extension
 import AFQ.utils.volume as auv
 from AFQ.definitions.mapping import SynMap
 from AFQ.definitions.utils import Definition
@@ -86,8 +87,8 @@ def export_rois(subses_dict, data_imap, mapping, dwi_affine):
                             nib.Nifti1Image(
                                 warped_roi.astype(np.float32),
                                 dwi_affine), fname)
-                        meta = dict()
-                        meta_fname = fname.split('.')[0] + '.json'
+                        meta = {}
+                        meta_fname = f'{drop_extension(fname)}.json'
                         write_json(meta_fname, meta)
                     roi_files[bundle].append(fname)
     return {'rois_file': roi_files}
diff --git a/AFQ/tasks/segmentation.py b/AFQ/tasks/segmentation.py
index 8fae0dff..42a8b994 100644
--- a/AFQ/tasks/segmentation.py
+++ b/AFQ/tasks/segmentation.py
@@ -11,6 +11,7 @@ import pimms
 from AFQ.tasks.decorators import as_file
 from AFQ.tasks.utils import get_fname, with_name
 import AFQ.segmentation as seg
+from AFQ.utils.path import drop_extension
 import AFQ.utils.streamlines as aus
 from AFQ.tasks.utils import get_default_args
 from AFQ.data.s3bids import write_json
@@ -178,7 +179,7 @@ def export_bundles(subses_dict, clean_bundles_file, bundles_file,
                     seg_sft.get_bundle(bundle), fname,
                     bbox_valid_check=False)
                 meta = dict(source=this_bundles_file)
-                meta_fname = fname.split('.')[0] + '.json'
+                meta_fname = drop_extension(fname) + '.json'
                 write_json(meta_fname, meta)
     return True
 
diff --git a/AFQ/utils/path.py b/AFQ/utils/path.py
new file mode 100644
index 00000000..cefefce2
--- /dev/null
+++ b/AFQ/utils/path.py
@@ -0,0 +1,6 @@
+import os.path as op
+
+
+def drop_extension(path):
+    base_fname = op.basename(path).split('.')[0]
+    return path.split(base_fname)[0] + base_fname
diff --git a/AFQ/utils/streamlines.py b/AFQ/utils/streamlines.py
index 53a23755..f35129f6 100644
--- a/AFQ/utils/streamlines.py
+++ b/AFQ/utils/streamlines.py
@@ -5,6 +5,8 @@ from dipy.io.stateful_tractogram import StatefulTractogram, Space
 from AFQ.data.s3bids import read_json
 import os.path as op
 
+from AFQ.utils.path import drop_extension
+
 
 class SegmentedSFT():
     def __init__(self, bundles, space):
@@ -60,7 +62,7 @@ class SegmentedSFT():
         if sidecar_file is None:
             # assume json sidecar has the same name as trk_file,
             # but with json suffix
-            sidecar_file = trk_file.split('.')[0] + '.json'
+            sidecar_file = f'{drop_extension(trk_file)}.json'
             if not op.exists(sidecar_file):
                 raise ValueError((
                     "JSON sidecars are required for trk files. "


Test patch:
diff --git a/AFQ/utils/tests/test_path.py b/AFQ/utils/tests/test_path.py
new file mode 100644
index 00000000..cabd9336
--- /dev/null
+++ b/AFQ/utils/tests/test_path.py
@@ -0,0 +1,9 @@
+from AFQ.utils.path import drop_extension
+
+
+def test_drop_extension():
+    assert "/my/.example/.path/to_file" == drop_extension(
+        "/my/.example/.path/to_file.nii.gz")
+
+    assert "C:\\Documents\\Newsletters\\Summer2018" == drop_extension(
+        "C:\\Documents\\Newsletters\\Summer2018.pdf.gz")