From bdc027722a282e7ae7a60e84bc004cc9f4f310d3 Mon Sep 17 00:00:00 2001 From: ClePol Date: Wed, 13 May 2026 15:45:36 +0200 Subject: [PATCH 1/4] Make surface reconstruction deterministic --- recon_surf/recon-surf.sh | 2 +- recon_surf/spherically_project_wrapper.py | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/recon_surf/recon-surf.sh b/recon_surf/recon-surf.sh index 8bfca5a82..4d1d648d7 100755 --- a/recon_surf/recon-surf.sh +++ b/recon_surf/recon-surf.sh @@ -794,7 +794,7 @@ for hemi in lh rh ; do echo "echo \"\"" } | tee -a "$CMDF" - cmd="recon-all -subject $subject -hemi $hemi -fix -no-isrunning -umask $(umask) $hiresflag $fsthreads" + cmd="env OMP_NUM_THREADS=1 ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS=1 recon-all -subject $subject -hemi $hemi -fix -no-isrunning -umask $(umask) $hiresflag -threads 1 -itkthreads 1" RunIt "$cmd" "$LF" "$CMDF" # fix the surfaces if they are corrupt diff --git a/recon_surf/spherically_project_wrapper.py b/recon_surf/spherically_project_wrapper.py index 09b3eb9bd..957c2a06e 100644 --- a/recon_surf/spherically_project_wrapper.py +++ b/recon_surf/spherically_project_wrapper.py @@ -48,8 +48,20 @@ def setup_options(): if __name__ == "__main__": import sys + from os import environ opts = setup_options() + # The spectral projection is sensitive to tiny threaded BLAS/eigensolver + # differences, and those can be amplified by later topology correction. + for var in ( + "OMP_NUM_THREADS", + "OPENBLAS_NUM_THREADS", + "MKL_NUM_THREADS", + "NUMEXPR_NUM_THREADS", + "VECLIB_MAXIMUM_THREADS", + ): + environ[var] = "1" + # identify whether sksparse is installed (in which case we can use_cholmod in LaPy try: # ignore ruff F401 (unused import) @@ -59,8 +71,6 @@ def setup_options(): has_sksparse = False # First try to run standard spherical project try: - from os import environ - from recon_surf.spherically_project import spherically_project_surface source_surface = opts.sd / opts.subject / "surf" / f"{opts.hemi}.smoothwm.nofix" From cc66fddc89cfaab7135b9e7fa9fb546680f3d5dc Mon Sep 17 00:00:00 2001 From: Clemens Pollak Date: Mon, 29 Jun 2026 18:15:45 +0200 Subject: [PATCH 2/4] Update recon_surf/recon-surf.sh Co-authored-by: Martin Reuter --- recon_surf/recon-surf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recon_surf/recon-surf.sh b/recon_surf/recon-surf.sh index 4d1d648d7..4da4cc97b 100755 --- a/recon_surf/recon-surf.sh +++ b/recon_surf/recon-surf.sh @@ -794,7 +794,7 @@ for hemi in lh rh ; do echo "echo \"\"" } | tee -a "$CMDF" - cmd="env OMP_NUM_THREADS=1 ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS=1 recon-all -subject $subject -hemi $hemi -fix -no-isrunning -umask $(umask) $hiresflag -threads 1 -itkthreads 1" + cmd="recon-all -subject $subject -hemi $hemi -fix -no-isrunning -umask $(umask) $hiresflag -threads 1 -itkthreads 1" RunIt "$cmd" "$LF" "$CMDF" # fix the surfaces if they are corrupt From b93744b7d6440893174cbdfe9d0f564e24ac1999 Mon Sep 17 00:00:00 2001 From: Martin Reuter Date: Wed, 1 Jul 2026 15:40:37 +0200 Subject: [PATCH 3/4] fixing to 1 thread here does not seem to be needed in my experiments on linux and mac --- recon_surf/recon-surf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recon_surf/recon-surf.sh b/recon_surf/recon-surf.sh index 4da4cc97b..8bfca5a82 100755 --- a/recon_surf/recon-surf.sh +++ b/recon_surf/recon-surf.sh @@ -794,7 +794,7 @@ for hemi in lh rh ; do echo "echo \"\"" } | tee -a "$CMDF" - cmd="recon-all -subject $subject -hemi $hemi -fix -no-isrunning -umask $(umask) $hiresflag -threads 1 -itkthreads 1" + cmd="recon-all -subject $subject -hemi $hemi -fix -no-isrunning -umask $(umask) $hiresflag $fsthreads" RunIt "$cmd" "$LF" "$CMDF" # fix the surfaces if they are corrupt From 025dbbd02510558d83ee73bb3e58a028e000ebec Mon Sep 17 00:00:00 2001 From: Martin Reuter Date: Wed, 1 Jul 2026 15:41:26 +0200 Subject: [PATCH 4/4] numexpr is not a dependency here --- recon_surf/spherically_project_wrapper.py | 1 - 1 file changed, 1 deletion(-) diff --git a/recon_surf/spherically_project_wrapper.py b/recon_surf/spherically_project_wrapper.py index 957c2a06e..fca12566c 100644 --- a/recon_surf/spherically_project_wrapper.py +++ b/recon_surf/spherically_project_wrapper.py @@ -57,7 +57,6 @@ def setup_options(): "OMP_NUM_THREADS", "OPENBLAS_NUM_THREADS", "MKL_NUM_THREADS", - "NUMEXPR_NUM_THREADS", "VECLIB_MAXIMUM_THREADS", ): environ[var] = "1"