|
97 | 97 | from time import strftime
|
98 | 98 | from typing import TYPE_CHECKING, Any, Iterable
|
99 | 99 | from uuid import uuid4
|
| 100 | +import random |
100 | 101 |
|
101 | 102 | try:
|
102 | 103 | # This option is only available with Python 3.8
|
@@ -674,11 +675,51 @@ def getLogger(cls, name) -> logging.Logger:
|
674 | 675 | return retval
|
675 | 676 |
|
676 | 677 |
|
| 678 | +class seeds(_Config): |
| 679 | + """Initialize the PRNG and track random seed assignments""" |
| 680 | + |
| 681 | + _random_seed = None |
| 682 | + master = None |
| 683 | + """Master random seed to initialize the Pseudorandom Number Generator (PRNG)""" |
| 684 | + ants = None |
| 685 | + """Seed used for antsRegistration, antsAI, antsMotionCorr""" |
| 686 | + numpy = None |
| 687 | + """Seed used by NumPy""" |
| 688 | + |
| 689 | + @classmethod |
| 690 | + def init(cls): |
| 691 | + if cls._random_seed is not None: |
| 692 | + cls.master = cls._random_seed |
| 693 | + if cls.master is None: |
| 694 | + cls.master = random.randint(1, 65536) |
| 695 | + random.seed(cls.master) # initialize the PRNG |
| 696 | + # functions to set program specific seeds |
| 697 | + cls.ants = _set_ants_seed() |
| 698 | + cls.numpy = _set_numpy_seed() |
| 699 | + |
| 700 | + |
| 701 | +def _set_ants_seed(): |
| 702 | + """Fix random seed for antsRegistration, antsAI, antsMotionCorr""" |
| 703 | + val = random.randint(1, 65536) |
| 704 | + os.environ['ANTS_RANDOM_SEED'] = str(val) |
| 705 | + return val |
| 706 | + |
| 707 | + |
| 708 | +def _set_numpy_seed(): |
| 709 | + """NumPy's random seed is independent from Python's `random` module""" |
| 710 | + import numpy as np |
| 711 | + |
| 712 | + val = random.randint(1, 65536) |
| 713 | + np.random.seed(val) |
| 714 | + return val |
| 715 | + |
| 716 | + |
677 | 717 | def from_dict(sections: dict) -> None:
|
678 | 718 | """Read settings from a flat dictionary."""
|
679 | 719 | execution.load(sections)
|
680 | 720 | workflow.load(sections)
|
681 | 721 | nipype.load(sections, init=False)
|
| 722 | + seeds.load(sections, init=False) |
682 | 723 |
|
683 | 724 |
|
684 | 725 | def load(filename: str | os.PathLike) -> None:
|
|
0 commit comments