Skip to content

Commit cb641e9

Browse files
Add option to fix the random seed
1 parent 20b03f6 commit cb641e9

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

mriqc/cli/parser.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,14 @@ def _bids_filter(value):
447447
default=False,
448448
help='Despike the functional scans during head motion correction preprocessing.',
449449
)
450+
g_func.add_argument(
451+
'--random-seed',
452+
dest='_random_seed',
453+
action='store',
454+
type=int,
455+
default=None,
456+
help='Initialize the random seed for the workflow',
457+
)
450458
g_func.add_argument(
451459
'--start-idx',
452460
action=DeprecateAction,
@@ -461,7 +469,6 @@ def _bids_filter(value):
461469
help='DEPRECATED Final volume in functional timeseries that should be '
462470
'considered for preprocessing.',
463471
)
464-
465472
latest = check_latest()
466473
if latest is not None and currentv < latest:
467474
print(

mriqc/config.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
from time import strftime
9999
from typing import TYPE_CHECKING, Any, Iterable
100100
from uuid import uuid4
101+
import random
101102

102103
try:
103104
# This option is only available with Python 3.8
@@ -696,11 +697,51 @@ def getLogger(cls, name) -> logging.Logger:
696697
return retval
697698

698699

700+
class seeds(_Config):
701+
"""Initialize the PRNG and track random seed assignments"""
702+
703+
_random_seed = None
704+
master = None
705+
"""Master random seed to initialize the Pseudorandom Number Generator (PRNG)"""
706+
ants = None
707+
"""Seed used for antsRegistration, antsAI, antsMotionCorr"""
708+
numpy = None
709+
"""Seed used by NumPy"""
710+
711+
@classmethod
712+
def init(cls):
713+
if cls._random_seed is not None:
714+
cls.master = cls._random_seed
715+
if cls.master is None:
716+
cls.master = random.randint(1, 65536)
717+
random.seed(cls.master) # initialize the PRNG
718+
# functions to set program specific seeds
719+
cls.ants = _set_ants_seed()
720+
cls.numpy = _set_numpy_seed()
721+
722+
723+
def _set_ants_seed():
724+
"""Fix random seed for antsRegistration, antsAI, antsMotionCorr"""
725+
val = random.randint(1, 65536)
726+
os.environ['ANTS_RANDOM_SEED'] = str(val)
727+
return val
728+
729+
730+
def _set_numpy_seed():
731+
"""NumPy's random seed is independent from Python's `random` module"""
732+
import numpy as np
733+
734+
val = random.randint(1, 65536)
735+
np.random.seed(val)
736+
return val
737+
738+
699739
def from_dict(sections: dict) -> None:
700740
"""Read settings from a flat dictionary."""
701741
execution.load(sections)
702742
workflow.load(sections)
703743
nipype.load(sections, init=False)
744+
seeds.load(sections, init=False)
704745

705746

706747
def load(filename: str | os.PathLike) -> None:

0 commit comments

Comments
 (0)