Skip to content

Commit

Permalink
Make PlotPeaks robust enough that we don't need --writable-tempfs in …
Browse files Browse the repository at this point in the history
…singularity/apptainer (#174)

* remove the nipype xvfb and try it directly in the plotting function

* Use xvfb in the cli function

---------

Co-authored-by: Taylor Salo <salot@pennmedicine.upenn.edu>
  • Loading branch information
mattcieslak and tsalo authored Nov 20, 2024
1 parent 01e31d6 commit 3d14e53
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 27 deletions.
73 changes: 54 additions & 19 deletions qsirecon/cli/recon_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ def recon_plot():
parser.add_argument("--padding", type=int, default=10, help="number of slices to plot")
opts = parser.parse_args()

print(f"TMPDIR={os.getenv('TMPDIR')}")
if opts.mif:
odf_img, directions = mif2amps(opts.mif, os.getcwd())
LOGGER.info("converting %s to plot ODF/peaks", opts.mif)
Expand All @@ -126,29 +125,65 @@ def recon_plot():
else:
background_data = nb.load(opts.background_image).get_fdata()

LOGGER.info("saving peaks image to %s", opts.peaks_image)
peak_slice_series(
odf_4d,
sphere,
background_data,
opts.peaks_image,
n_cuts=opts.ncuts,
mask_image=opts.mask_file,
padding=opts.padding,
)
LOGGER.info("Starting a virtual framebuffer for FURY")

# Plot ODFs in interesting regions
if opts.odf_rois and not opts.peaks_only:
LOGGER.info("saving odfs image to %s", opts.odfs_image)
odf_roi_plot(
# Xvfb won't allow an empty $DISPLAY
if "DISPLAY" in os.environ:
del os.environ["DISPLAY"]

from xvfbwrapper import Xvfb

display = Xvfb(nolisten="tcp")
display.extra_xvfb_args += ["+iglx"]

try:
display.start()
except Exception as exc:
LOGGER.warning(
"Unable to start Xvfb!! If you are running this via Apptainer/Singularity "
"there may be an issue accessing the /tmp directory.\n\n"
"If you used the --containall flag, please also use --writable-tmpfs.\n\n"
"Otherwise, be sure that the /tmp directory is writable by Singularity/Apptainer. "
"This may require contacting a system administrator.\n\n"
f"The python error was\n{exc}"
)
sys.exit(1)

try:
peak_slice_series(
odf_4d,
sphere,
background_data,
opts.odfs_image,
opts.odf_rois,
subtract_iso=opts.subtract_iso,
mask=opts.mask_file,
opts.peaks_image,
n_cuts=opts.ncuts,
mask_image=opts.mask_file,
padding=opts.padding,
)
except Exception as exc:
LOGGER.warning(exc)
sys.exit(1)

LOGGER.info("saving peaks image to %s", opts.peaks_image)

# Plot ODFs in interesting regions
if opts.odf_rois and not opts.peaks_only:
try:
odf_roi_plot(
odf_4d,
sphere,
background_data,
opts.odfs_image,
opts.odf_rois,
subtract_iso=opts.subtract_iso,
mask=opts.mask_file,
)
except Exception as exc:
LOGGER.warning(exc)
sys.exit(1)

LOGGER.info("saved odfs image to %s", opts.odfs_image)

display.stop()
sys.exit(0)


Expand Down
1 change: 0 additions & 1 deletion qsirecon/interfaces/reports.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,6 @@ class CLIReconPeaksReport(CommandLine):
input_spec = _ReconPeaksReportInputSpec
output_spec = _ReconPeaksReportOutputSpec
_cmd = "recon_plot"
_redirect_x = True

def _list_outputs(self):
outputs = self.output_spec().get()
Expand Down
2 changes: 1 addition & 1 deletion qsirecon/workflows/recon/amico.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def init_amico_noddi_fit_wf(

if plot_reports:
plot_peaks = pe.Node(
CLIReconPeaksReport(environ={"TMPDIR": str(config.execution.work_dir)}),
CLIReconPeaksReport(),
name="plot_peaks",
n_procs=omp_nthreads,
)
Expand Down
4 changes: 2 additions & 2 deletions qsirecon/workflows/recon/dipy.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ def init_dipy_brainsuite_shore_recon_wf(

if plot_reports:
plot_peaks = pe.Node(
CLIReconPeaksReport(environ={"TMPDIR": str(config.execution.work_dir)}),
CLIReconPeaksReport(),
name="plot_peaks",
n_procs=omp_nthreads,
)
Expand Down Expand Up @@ -500,7 +500,7 @@ def init_dipy_mapmri_recon_wf(

if plot_reports:
plot_peaks = pe.Node(
CLIReconPeaksReport(environ={"TMPDIR": str(config.execution.work_dir)}),
CLIReconPeaksReport(),
name="plot_peaks",
n_procs=omp_nthreads,
)
Expand Down
4 changes: 1 addition & 3 deletions qsirecon/workflows/recon/dsi_studio.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,7 @@ def init_dsi_studio_recon_wf(inputs_dict, name="dsi_studio_recon", qsirecon_suff
if plot_reports:
# Make a visual report of the model
plot_peaks = pe.Node(
CLIReconPeaksReport(
environ={"TMPDIR": str(config.execution.work_dir)}, subtract_iso=True
),
CLIReconPeaksReport(subtract_iso=True),
name="plot_peaks",
n_procs=omp_nthreads,
)
Expand Down
2 changes: 1 addition & 1 deletion qsirecon/workflows/recon/mrtrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ def init_mrtrix_csd_recon_wf(inputs_dict, name="mrtrix_recon", qsirecon_suffix="
if not config.execution.skip_odf_reports:
# Make a visual report of the model
plot_peaks = pe.Node(
CLIReconPeaksReport(environ={"TMPDIR": str(config.execution.work_dir)}),
CLIReconPeaksReport(),
name="plot_peaks",
n_procs=omp_nthreads,
)
Expand Down

0 comments on commit 3d14e53

Please sign in to comment.