|
98 | 98 | from time import strftime
|
99 | 99 | from typing import TYPE_CHECKING, Any, Iterable
|
100 | 100 | from uuid import uuid4
|
| 101 | +import random |
101 | 102 |
|
102 | 103 | try:
|
103 | 104 | # This option is only available with Python 3.8
|
@@ -696,11 +697,51 @@ def getLogger(cls, name) -> logging.Logger:
|
696 | 697 | return retval
|
697 | 698 |
|
698 | 699 |
|
| 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 | + |
699 | 739 | def from_dict(sections: dict) -> None:
|
700 | 740 | """Read settings from a flat dictionary."""
|
701 | 741 | execution.load(sections)
|
702 | 742 | workflow.load(sections)
|
703 | 743 | nipype.load(sections, init=False)
|
| 744 | + seeds.load(sections, init=False) |
704 | 745 |
|
705 | 746 |
|
706 | 747 | def load(filename: str | os.PathLike) -> None:
|
|
0 commit comments