Skip to content

Commit 03e433f

Browse files
committed
Merge branch 'main' into bids-atlas-update
2 parents ba520da + 72555de commit 03e433f

File tree

17 files changed

+259
-142
lines changed

17 files changed

+259
-142
lines changed

docs/api.rst

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,5 @@ Library API
1818
***********
1919

2020
.. toctree::
21-
:glob:
2221

23-
api/xcp_d.cli
24-
api/xcp_d.workflows
25-
api/xcp_d.interfaces
26-
api/xcp_d.utils
27-
api/xcp_d.ingression
22+
api/xcp_d

docs/workflows.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ The ``--skip`` parameter accepts the following options:
352352
Historically, users could pass the legacy ``--skip-parcellation`` flag to
353353
achieve this behavior. That flag is now deprecated — use
354354
``--skip parcellation`` instead.
355+
355356
**Note that skipping parcellation will automatically skip connectivity as well,
356357
since connectivity requires parcellated data.**
357358

xcp_d/config.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
The module has a :py:func:`~xcp_d.config.to_filename` function to allow writing out
3232
the settings to hard disk in *ToML* format, which looks like:
3333
34-
.. literalinclude:: ../xcp_d/data/tests/config.toml
34+
.. literalinclude:: ../../xcp_d/data/tests/config.toml
3535
:language: toml
3636
:name: xcp_d.toml
3737
:caption: **Example file representation of XCP-D settings**.
@@ -43,12 +43,16 @@
4343
----------------------
4444
.. autoclass:: environment
4545
:members:
46+
:no-index:
4647
.. autoclass:: execution
4748
:members:
49+
:no-index:
4850
.. autoclass:: workflow
4951
:members:
52+
:no-index:
5053
.. autoclass:: nipype
5154
:members:
55+
:no-index:
5256
5357
Usage
5458
-----
@@ -75,6 +79,7 @@
7579
-------
7680
.. autoclass:: loggers
7781
:members:
82+
:no-index:
7883
7984
Other responsibilities
8085
----------------------

xcp_d/data/tests/config.toml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,15 @@ run_uuid = "20240205-123456"
2626
templateflow_home = "~/.cache/templateflow"
2727
work_dir = "work/"
2828
write_graph = false
29+
atlases = ["Gordon"]
2930

3031
[workflow]
31-
cifti = false
32+
file_format = "nifti"
3233
dummy_scans = 0
3334
input_type = "fmriprep"
3435
despike = false
3536
smoothing = 6
3637
combine_runs = false
37-
motion_filter_type = false
38-
band_stop_min = false
39-
band_stop_max = false
4038
motion_filter_order = 4
4139
head_radius = 50
4240
fd_thresh = 0.3
@@ -45,7 +43,6 @@ bandpass_filter = true
4543
high_pass = 0.01
4644
low_pass = 0.1
4745
bpf_order = 2
48-
atlases = []
4946
min_coverage = 0.5
5047
correlation_lengths = []
5148
process_surfaces = false

xcp_d/interfaces/plotting.py

Lines changed: 91 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -241,19 +241,24 @@ class QCPlots(SimpleInterface):
241241
Examples
242242
--------
243243
.. testsetup::
244-
>>> from tempfile import TemporaryDirectory
245-
>>> tmpdir = TemporaryDirectory()
246-
>>> os.chdir(tmpdir.name)
244+
245+
>>> from tempfile import TemporaryDirectory
246+
>>> tmpdir = TemporaryDirectory()
247+
>>> os.chdir(tmpdir.name)
248+
247249
.. doctest::
248-
qcplots = QCPlots()
249-
qcplots.inputs.cleaned_file = datafile
250-
qcplots.inputs.bold_file = rawbold
251-
qcplots.inputs.TR = TR
252-
qcplots.inputs.temporal_mask = temporalmask
253-
qcplots.inputs.mask_file = mask
254-
qcplots.run()
250+
251+
qcplots = QCPlots()
252+
qcplots.inputs.cleaned_file = datafile
253+
qcplots.inputs.bold_file = rawbold
254+
qcplots.inputs.TR = TR
255+
qcplots.inputs.temporal_mask = temporalmask
256+
qcplots.inputs.mask_file = mask
257+
qcplots.run()
258+
255259
.. testcleanup::
256-
>>> tmpdir.cleanup()
260+
261+
>>> tmpdir.cleanup()
257262
"""
258263

259264
input_spec = _QCPlotsInputSpec
@@ -525,8 +530,9 @@ class _SlicesDirInputSpec(FSLCommandInputSpec):
525530
desc='output every second axial slice rather than just 9 ortho slices',
526531
)
527532

533+
# Copy in_files from the original location to the runtime.cwd
528534
in_files = InputMultiPath(
529-
File(exists=True),
535+
File(exists=True, copyfile=False),
530536
argstr='%s',
531537
mandatory=True,
532538
position=-1,
@@ -551,17 +557,70 @@ class SlicesDir(FSLCommand):
551557
552558
Notes
553559
-----
554-
Usage: slicesdir [-o] [-p <image>] [-e <thr>] [-S] <filelist>
555-
-o : filelist is pairs ( <underlying> <red-outline> ) of images
556-
-p <image> : use <image> as red-outline image on top of all images in <filelist>
557-
-e <thr> : use the specified threshold for edges (if >0 use this proportion of max-min,
558-
if <0, use the absolute value)
559-
-S : output every second axial slice rather than just 9 ortho slices
560+
Usage: ``slicesdir [-o] [-p <image>] [-e <thr>] [-S] <filelist>``
561+
562+
- ``-o`` : filelist is pairs ( <underlying> <red-outline> ) of images
563+
- ``-p <image>`` : use <image> as red-outline image on top of all images in <filelist>
564+
- ``-e <thr>`` : use the specified threshold for edges (if >0 use this proportion of
565+
max-min, if <0, use the absolute value)
566+
- ``-S`` : output every second axial slice rather than just 9 ortho slices
560567
"""
561568

562569
_cmd = 'slicesdir'
563570
input_spec = _SlicesDirInputSpec
564571
output_spec = _SlicesDirOutputSpec
572+
_short_basenames = None
573+
_short_outline = None
574+
575+
def _run_interface(self, runtime):
576+
"""Create symlinks with short names before running slicesdir.
577+
578+
``slicesdir`` names its output files by replacing path separators in the input
579+
file paths with underscores. When input paths are long (e.g., in deep working
580+
directories), the derived output filenames can exceed the OS's 255-character
581+
filename limit (see https://github.com/PennLINC/xcp_d/issues/1545).
582+
583+
We work around this by creating symlinks with short names in the working
584+
directory, and passing those short names to ``slicesdir`` instead of the
585+
original long paths.
586+
"""
587+
self._short_basenames = []
588+
for i, f in enumerate(self.inputs.in_files):
589+
ext = '.nii.gz' if f.endswith('.nii.gz') else os.path.splitext(f)[1]
590+
basename = f'img{i}{ext}'
591+
symlink_path = os.path.join(runtime.cwd, basename)
592+
if os.path.lexists(symlink_path):
593+
os.unlink(symlink_path)
594+
595+
os.symlink(os.path.abspath(f), symlink_path)
596+
self._short_basenames.append(basename)
597+
598+
if isdefined(self.inputs.outline_image):
599+
f = self.inputs.outline_image
600+
ext = '.nii.gz' if f.endswith('.nii.gz') else os.path.splitext(f)[1]
601+
self._short_outline = f'outline{ext}'
602+
symlink_path = os.path.join(runtime.cwd, self._short_outline)
603+
if os.path.lexists(symlink_path):
604+
os.unlink(symlink_path)
605+
606+
os.symlink(os.path.abspath(f), symlink_path)
607+
608+
runtime = super()._run_interface(runtime)
609+
return runtime
610+
611+
def _format_arg(self, name, spec, value):
612+
"""Use short symlink basenames for in_files and outline_image.
613+
614+
This ensures the ``slicesdir`` command line uses short paths, producing
615+
short output filenames that won't exceed the OS filename length limit.
616+
"""
617+
if name == 'in_files' and self._short_basenames is not None:
618+
return ' '.join(self._short_basenames)
619+
620+
if name == 'outline_image' and self._short_outline is not None:
621+
return spec.argstr % self._short_outline
622+
623+
return super()._format_arg(name, spec, value)
565624

566625
def _list_outputs(self):
567626
"""Create a Bunch which contains all possible files generated by running the interface.
@@ -580,13 +639,21 @@ def _list_outputs(self):
580639

581640
out_dir = os.path.abspath(os.path.join(os.getcwd(), 'slicesdir'))
582641
outputs['out_dir'] = out_dir
642+
643+
# Use short basenames if available (set by _run_interface),
644+
# otherwise fall back to the original path-based naming.
645+
if self._short_basenames is not None:
646+
in_basenames = self._short_basenames
647+
else:
648+
in_basenames = [f.replace(os.sep, '_') for f in self.inputs.in_files]
649+
583650
outputs['out_files'] = [
584651
self._gen_fname(
585-
basename=f.replace(os.sep, '_'),
652+
basename=name,
586653
cwd=out_dir,
587654
ext=self.inputs.out_extension,
588655
)
589-
for f in self.inputs.in_files
656+
for name in in_basenames
590657
]
591658
temp_files = [
592659
'grota.png',
@@ -633,9 +700,10 @@ class PNGAppend(FSLCommand):
633700
634701
Usage: pngappend <input 1> <+|-> [n] <input 2> [<+|-> [n] <input n>] output>
635702
636-
+ appends horizontally,
637-
- appends vertically (i.e. works like a linebreak)
638-
[n] number ofgap pixels
703+
- ``+`` appends horizontally,
704+
- ``-`` appends vertically (i.e. works like a linebreak)
705+
- ``[n]`` number of gap pixels
706+
639707
note that files with .gif extension will be input/output in GIF format
640708
"""
641709

xcp_d/interfaces/restingstate.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,21 @@ class SurfaceReHo(SimpleInterface):
4848
Examples
4949
--------
5050
.. testsetup::
51-
>>> from tempfile import TemporaryDirectory
52-
>>> tmpdir = TemporaryDirectory()
53-
>>> os.chdir(tmpdir.name)
51+
52+
>>> from tempfile import TemporaryDirectory
53+
>>> tmpdir = TemporaryDirectory()
54+
>>> os.chdir(tmpdir.name)
55+
5456
.. doctest::
55-
>>> surfacereho_wf = SurfaceReHo()
56-
>>> surfacereho_wf.inputs.surf_bold = 'rhhemi.func.gii'
57-
>>> surfacereho_wf.inputs.surf_hemi = 'R'
58-
>>> surfacereho_wf.run()
57+
58+
>>> surfacereho_wf = SurfaceReHo()
59+
>>> surfacereho_wf.inputs.surf_bold = 'rhhemi.func.gii'
60+
>>> surfacereho_wf.inputs.surf_hemi = 'R'
61+
>>> surfacereho_wf.run()
62+
5963
.. testcleanup::
60-
>>> tmpdir.cleanup()
64+
65+
>>> tmpdir.cleanup()
6166
"""
6267

6368
input_spec = _SurfaceReHoInputSpec

xcp_d/interfaces/workbench.py

Lines changed: 47 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -813,61 +813,53 @@ class ShowScene(WBCommand):
813813
814814
Notes
815815
-----
816-
wb_command -show-scene
817-
<scene-file> - scene file
818-
<scene-name-or-number> - name or number (starting at one) of the scene in
819-
the scene file
820-
<image-file-name> - output image file name
821-
<image-width> - width of output image(s), in pixels
822-
<image-height> - height of output image(s), in pixels
823-
824-
[-use-window-size] - Override image size with window size
825-
826-
[-no-scene-colors] - Do not use background and foreground colors in scene
827-
828-
[-set-map-yoke] - Override selected map index for a map yoking group.
829-
<Map Yoking Roman Numeral> - Roman numeral identifying the map yoking
830-
group (I, II, III, IV, V, VI, VII, VIII, IX, X)
831-
<Map Index> - Map index for yoking group. Indices start at 1 (one)
832-
833-
[-conn-db-login] - Login for scenes with files in Connectome Database
834-
<Username> - Connectome DB Username
835-
<Password> - Connectome DB Password
836-
837-
Render content of browser windows displayed in a scene into image
838-
file(s). The image file name should be similar to "capture.png". If
839-
there is only one image to render, the image name will not change. If
840-
there is more than one image to render, an index will be inserted into
841-
the image name: "capture_01.png", "capture_02.png" etc.
842-
843-
If the scene references files in the Connectome Database,
844-
the "-conn-db-login" option is available for providing the
845-
username and password. If this options is not specified,
846-
the username and password stored in the user's preferences
847-
is used.
848-
849-
The image format is determined by the image file extension.
850-
The available image formats may vary by operating system.
851-
Image formats available on this system are:
852-
bmp
853-
jpeg
854-
jpg
855-
png
856-
ppm
857-
tif
858-
tiff
859-
860-
The result of using the "-use-window-size" option
861-
is dependent upon the version used to create the scene.
862-
* Versions 1.2 and newer contain the width and
863-
height of the graphics region. The output image
864-
will be the width and height from the scene and
865-
the image width and height specified on the command
866-
line is ignored.
867-
* If the scene does not contain the width and height
868-
of the graphics region, the width and height specified
869-
on the command line is used for the size of the
870-
output image.
816+
``wb_command -show-scene``
817+
818+
Positional arguments:
819+
820+
- ``<scene-file>`` - scene file
821+
- ``<scene-name-or-number>`` - name or number (starting at one) of the scene in
822+
the scene file
823+
- ``<image-file-name>`` - output image file name
824+
- ``<image-width>`` - width of output image(s), in pixels
825+
- ``<image-height>`` - height of output image(s), in pixels
826+
827+
Optional arguments:
828+
829+
- ``[-use-window-size]`` - Override image size with window size
830+
- ``[-no-scene-colors]`` - Do not use background and foreground colors in scene
831+
- ``[-set-map-yoke]`` - Override selected map index for a map yoking group.
832+
- ``[-conn-db-login]`` - Login for scenes with files in Connectome Database
833+
834+
Render content of browser windows displayed in a scene into image
835+
file(s). The image file name should be similar to "capture.png". If
836+
there is only one image to render, the image name will not change. If
837+
there is more than one image to render, an index will be inserted into
838+
the image name: "capture_01.png", "capture_02.png" etc.
839+
840+
If the scene references files in the Connectome Database,
841+
the ``-conn-db-login`` option is available for providing the
842+
username and password. If this option is not specified,
843+
the username and password stored in the user's preferences
844+
is used.
845+
846+
The image format is determined by the image file extension.
847+
The available image formats may vary by operating system.
848+
Image formats available on this system are:
849+
bmp, jpeg, jpg, png, ppm, tif, tiff.
850+
851+
The result of using the ``-use-window-size`` option
852+
is dependent upon the version used to create the scene.
853+
854+
* Versions 1.2 and newer contain the width and
855+
height of the graphics region. The output image
856+
will be the width and height from the scene and
857+
the image width and height specified on the command
858+
line is ignored.
859+
* If the scene does not contain the width and height
860+
of the graphics region, the width and height specified
861+
on the command line is used for the size of the
862+
output image.
871863
"""
872864

873865
input_spec = _ShowSceneInputSpec

0 commit comments

Comments
 (0)