Ejemplo n.º 1
0
def resolveMarkupInclusions(
    src: Union[io.TextIOBase, pathlib.Path],
    typ: str = None,
    root: Optional[pathlib.Path] = None,
) -> io.StringIO:
    """
    Process a YAML stream, appropriately handling ``!include`` tags."

    This will take the passed string or file path, and attempt to parse it as YAML. In
    the process, any instances of ``!include [path]`` will be replaced with the
    appropriate contents of the ``!include`` file.

    Parameters
    ----------
    src : TextIOBase or Path
        If a Path is provided, read YAML from there. If is stream is provided, consume
        read text from the stream. If a stream is provided, ``root`` must also be
        provided.
    typ : str
        A valid parse type for the ruamel YAML library. Defaults to "rt" to preserve
        round-trip data.
    root : Optional Path
        The root directory to use for resolving relative paths in !include tags. If a
        stream is provided for ``src``, ``root`` must be provided. Otherwise, the
        directory containing the ``src`` path will be used by default.

    Notes
    -----
    This does a full (albeit not Yamlize) parse of the input YAML into the appropriate
    data structure, resolving the textual inclusions along the way. Then, the resulting
    data are re-serialized to a new YAML stream. As such, this is not super efficient.
    We do it this way because we don't have a whole lot of control over how yamlize
    handles the parsing. For instance, yamlize will not honor the custom !include tag.
    This sort of makes sense, as yamlize and YAML tags are two distinct approaches to
    representing custom objects in YAML.

    For now, this is not handling cross-document anchors and aliases, which sucks. We
    may wish to resolve this, but methods to do so are rather complex and not without
    their own drawbacks. There is some pure gold on that topic here:
    https://stackoverflow.com/questions/44910886/pyyaml-include-file-and-yaml-aliases-anchors-references
    """
    registerYamlIncludeConstructor()

    if isinstance(src, pathlib.Path):
        root = root or src.parent.absolute()
    else:
        root = root or pathlib.Path(os.getcwd()).absolute()

    with directoryChangers.DirectoryChanger(root):
        yaml = ruamel.yaml.YAML(typ=typ, pure=True)
        data = yaml.load(src)

    out = io.StringIO()

    yaml.dump(data, out)
    out.seek(0)
    if isinstance(src, io.TextIOBase):
        src.seek(0)

    return out
Ejemplo n.º 2
0
 def setUpClass(cls):
     # prepare the input files. This is important so the unit tests run from wherever
     # they need to run from.
     cls.directoryChanger = directoryChangers.DirectoryChanger(
         TEST_ROOT, dumpOnException=False
     )
     cls.directoryChanger.open()
Ejemplo n.º 3
0
 def blueprintsHasOldXSInput(path):
     with directoryChangers.DirectoryChanger(inspector.cs.inputDirectory):
         with open(os.path.expandvars(path)) as f:
             for line in f:
                 if line.startswith("cross sections:"):
                     return True
     return False
Ejemplo n.º 4
0
    def _setGeomType(self):
        if self.cs["geomFile"]:
            with directoryChangers.DirectoryChanger(self.cs.inputDirectory):
                geom = geometry.SystemLayoutInput()
                geom.readGeomFromFile(self.cs["geomFile"])

            self.geomType, self.coreSymmetry = geom.geomType, geom.symmetry
Ejemplo n.º 5
0
    def _setGeomType(self):
        if self.cs["geomFile"]:
            with directoryChangers.DirectoryChanger(self.cs.inputDirectory,
                                                    dumpOnException=False):
                geom = systemLayoutInput.SystemLayoutInput()
                geom.readGeomFromFile(self.cs["geomFile"])

            self.geomType, self.coreSymmetry = geom.geomType, geom.symmetry
Ejemplo n.º 6
0
def loadFromCs(cs):
    """Function to load Geoemtry based on supplied ``CaseSettings``."""
    from armi.utils import directoryChangers  # circular import protection

    with directoryChangers.DirectoryChanger(cs.inputDirectory):
        geom = SystemLayoutInput()
        geom.readGeomFromFile(cs["geomFile"])
        return geom
Ejemplo n.º 7
0
    def setUpClass(cls):
        cls.cs = settings.Settings()
        cls.directoryChanger = directoryChangers.DirectoryChanger(TEST_ROOT)
        cls.directoryChanger.open()

        y = textProcessors.resolveMarkupInclusions(
            pathlib.Path(os.getcwd()) / "refSmallReactor.yaml")
        cls.blueprints = blueprints.Blueprints.load(y)
        cls.blueprints._prepConstruction(cls.cs)
Ejemplo n.º 8
0
    def setUpClass(cls):
        cls.cs = settings.Settings()
        cls.directoryChanger = directoryChangers.DirectoryChanger(TEST_ROOT)
        cls.directoryChanger.open()
        isotopicDepletion.applyDefaultBurnChain()

        with open("refSmallReactor.yaml", "r") as y:
            cls.blueprints = blueprints.Blueprints.load(y)
            cls.blueprints._prepConstruction("hex", cls.cs)
Ejemplo n.º 9
0
    def loadFromCs(cls, cs):
        """Function to load Geoemtry based on supplied ``CaseSettings``."""

        if not cs["geomFile"]:
            return None
        with directoryChangers.DirectoryChanger(cs.inputDirectory):
            geom = cls()
            geom.readGeomFromFile(cs["geomFile"])
            return geom
Ejemplo n.º 10
0
def runTutorialNotebook():
    import nbformat
    from nbconvert.preprocessors import ExecutePreprocessor

    with directoryChangers.DirectoryChanger(TUTORIAL_DIR):
        with open("data_model.ipynb") as f:
            nb = nbformat.read(f, as_version=4)
        ep = ExecutePreprocessor(timeout=600, kernel_name="python")
        ep.preprocess(nb, {})
Ejemplo n.º 11
0
def loadFromCs(cs):
    """Function to load Geoemtry based on supplied ``CaseSettings``."""
    from armi.utils import directoryChangers  # pylint: disable=import-outside-toplevel; circular import protection
    if not cs["geomFile"]:
        return None
    with directoryChangers.DirectoryChanger(cs.inputDirectory):
        geom = SystemLayoutInput()
        geom.readGeomFromFile(cs["geomFile"])
        return geom
Ejemplo n.º 12
0
 def invoke(self):
     """
     Run the entry point
     """
     if self.args.settings_path:
         path, _fname = os.path.split(self.args.settings_path)
         with directoryChangers.DirectoryChanger(path, dumpOnException=False):
             self._migrate(self.args.settings_path, self.args.database_path)
     else:
         self._migrate(self.args.settings_path, self.args.database_path)
Ejemplo n.º 13
0
 def test_getFullFileNames(self):
     with directoryChangers.DirectoryChanger(THIS_DIR):
         baseCall = pathTools.getFullFileNames()
         # all variations should return the same values.
         self.assertEqual(pathTools.getFullFileNames(),
                          pathTools.getFullFileNames(THIS_DIR))
         self.assertEqual(
             pathTools.getFullFileNames(recursive=True),
             pathTools.getFullFileNames(THIS_DIR, recursive=True),
         )
Ejemplo n.º 14
0
 def invoke(self):
     with directoryChangers.DirectoryChanger(
         self.args.suiteDir, dumpOnException=False
     ):
         suite = cases.CaseSuite(self.cs)
         suite.discover(patterns=self.args.patterns, ignorePatterns=self.args.ignore)
         if self.args.list:
             suite.echoConfiguration()
         else:
             suite.run()
Ejemplo n.º 15
0
    def _setup_blueprints(self):
        # need this for the getAllNuclides call
        with directoryChangers.DirectoryChanger(TEST_ROOT):
            self.cs["loadingFile"] = "refSmallReactor.yaml"
            with open(self.cs["loadingFile"], "r") as y:
                y = textProcessors.resolveMarkupInclusions(
                    y, pathlib.Path(self.cs.inputDirectory))
                self.r.blueprints = blueprints.Blueprints.load(y)

            self.r.blueprints._prepConstruction(self.cs)
    def setUpClass(cls):
        o, r = test_reactors.loadTestReactor()
        opts = executionOptions.Dif3dOptions("test-output-file")
        opts.fromUserSettings(o.cs)
        opts.resolveDerivedOptions()
        opts.fromReactor(r)
        with directoryChangers.DirectoryChanger(FIXTURE_DIR):
            outputReader = outputReaders.Dif3dReader(opts)
            outputReader.apply(r)

        cls.r = r
Ejemplo n.º 17
0
    def invoke(self):
        srcDB = db.databaseFactory(dbName=self.args.srcDB,
                                   permission=db.Permissions.READ_ONLY_FME)
        tarDB = db.databaseFactory(dbName=self.args.tarDB,
                                   permission=db.Permissions.CREATE_FILE_TIE)

        cs = settings.Settings(fName=self.args.csPath)

        with directoryChangers.DirectoryChanger(cs.inputDirectory):
            o = armi.init(cs=cs)
            db.copyDatabase(o.r, srcDB, tarDB)
Ejemplo n.º 18
0
 def setUpClass(cls):
     runTutorialNotebook()
     with directoryChangers.DirectoryChanger(TUTORIAL_DIR):
         reloadCs = settings.Settings(f"{CASE_TITLE}.yaml")
         reloadCs.caseTitle = "armiRun"
         reloadCs["db"] = True
         reloadCs["reloadDBName"] = f"{CASE_TITLE}.h5"
         reloadCs["runType"] = "Snapshots"
         reloadCs["loadStyle"] = "fromDB"
         reloadCs["detailAssemLocationsBOL"] = ["A1001"]
         o = armi.init(cs=reloadCs)
         cls.o = o
Ejemplo n.º 19
0
 def invoke(self):
     with directoryChangers.DirectoryChanger(self.args.suiteDir,
                                             dumpOnException=False):
         suite = cases.CaseSuite(self.cs)
         suite.discover(patterns=self.args.patterns,
                        ignorePatterns=self.args.ignore)
         if self.args.list:
             suite.echoConfiguration()
         else:
             for ci, case in enumerate(suite):
                 runLog.important(
                     f"Running case {ci+1}/{len(suite)}: {case}")
                 with directoryChangers.DirectoryChanger(case.directory):
                     settings.setMasterCs(case.cs)
                     case.run()
Ejemplo n.º 20
0
def loadFromCs(cs):
    """
    Function to load Blueprints based on supplied ``CaseSettings``.
    """
    from armi.utils import directoryChangers  # circular import protection

    with directoryChangers.DirectoryChanger(cs.inputDirectory):
        with open(cs["loadingFile"], "r") as bpYaml:
            try:
                bp = Blueprints.load(bpYaml)
            except yamlize.yamlizing_error.YamlizingError as err:
                if "cross sections" in err.args[0]:
                    runLog.error(
                        "The loading file {} contains invalid `cross sections` input. "
                        "Please run the `modify` entry point on this case to automatically convert."
                        "".format(cs["loadingFile"]))
                raise
    return bp
Ejemplo n.º 21
0
def loadFromCs(cs):
    """
    Function to load Blueprints based on supplied ``CaseSettings``.
    """
    # pylint: disable=import-outside-toplevel; circular import protection
    from armi.utils import directoryChangers

    with directoryChangers.DirectoryChanger(cs.inputDirectory,
                                            dumpOnException=False):
        with open(cs["loadingFile"], "r") as bpYaml:
            root = pathlib.Path(cs["loadingFile"]).parent.absolute()
            bpYaml = textProcessors.resolveMarkupInclusions(bpYaml, root)
            try:
                bp = Blueprints.load(bpYaml)
            except yamlize.yamlizing_error.YamlizingError as err:
                if "cross sections" in err.args[0]:
                    runLog.error(
                        "The loading file {} contains invalid `cross sections` input. "
                        "Please run the `modify` entry point on this case to automatically convert."
                        "".format(cs["loadingFile"]))
                raise
    return bp
Ejemplo n.º 22
0
def loadFromCs(cs):
    """
    Function to load Blueprints based on supplied ``CaseSettings``.
    """
    # pylint: disable=import-outside-toplevel; circular import protection
    from armi.utils import directoryChangers

    textProcessors.registerYamlIncludeConstructor()

    with directoryChangers.DirectoryChanger(cs.inputDirectory):
        with open(cs["loadingFile"], "r") as bpYaml:
            # Make sure that the !include constructor is registered
            bpYaml = textProcessors.resolveMarkupInclusions(bpYaml)
            try:
                bp = Blueprints.load(bpYaml)
            except yamlize.yamlizing_error.YamlizingError as err:
                if "cross sections" in err.args[0]:
                    runLog.error(
                        "The loading file {} contains invalid `cross sections` input. "
                        "Please run the `modify` entry point on this case to automatically convert."
                        "".format(cs["loadingFile"]))
                raise
    return bp
Ejemplo n.º 23
0
def createTestXSLibraryFiles(cachePath):
    r"""This method is used to generate 5 ISOTXS files used during testing.

    Notes
    -----
    It runs a batch file pointing to the MC**2-v3 executable with MC**2-v3 inputs within the repository,
    instead of placing the larger binary ISOTXS files within the repository.

    Also, the _CREATE_ERROR module attribute is used to track whether we have already tried to generate
    ISOTXS files. Basically, this method can (and should) be called in the setUp/setUpClass of any test
    that uses the generated ISOTXS files. Therefore, it is possible that for some reason the ISOTXS
    generation fails, and it would not be worth the time to continually try to recreate the ISOTXS files
    for each test that uses them, instead just raise the error that occurred the first time.
    """
    cs = settings.Settings()
    cs["outputCacheLocation"] = cachePath
    mc2v3 = cs.get("mc2v3.path").default
    with directoryChangers.DirectoryChanger(RUN_DIR):
        # the two lines below basically copy the inputs to be used for PMATRX and GAMISO generation.
        # Since they are inputs to secondary calculations, the inputs need to be created before any
        # other output is generated. Do not move the two lines below to, for exmaple just before they
        # are used, otherwise the input to the GAMISO calculation would be younger than the output
        # DLAYXS, which would cause this the @fixture to determine that targets are out of date.
        # The result would be that the targets will never be up to date, which defeats the purpose ;-).
        # IMPORTANT!! these two lines cannot move!
        copyInputForPmatrxAndGamsio("combine-AA-AB.inp")
        copyInputForPmatrxAndGamsio("combine-and-lump-AA-AB.inp")
        # IMPORTANT!! these two lines cannot move!
        ############################################################
        ##                                                        ##
        ##                   GENERATE DLAYXS                      ##
        ##                                                        ##
        ############################################################
        outputCache.cacheCall(cs["outputCacheLocation"], mc2v3,
                              ["mc2v3-dlayxs.inp"], ["DLAYXS"])
        shutil.move("DLAYXS", DLAYXS_MCC3)

        ############################################################
        ##                                                        ##
        ##                   GENERATE ISOTXS                      ##
        ##                                                        ##
        ############################################################
        outputCache.cacheCall(
            cs["outputCacheLocation"],
            mc2v3,
            ["mc2v3-AA.inp"],
            [
                "ISOTXS.merged", "GAMISO.merged", "PMATRX.merged",
                "output.flux_ufg"
            ],
        )
        shutil.move("ISOTXS.merged", ISOTXS_AA)
        shutil.move("GAMISO.merged", GAMISO_AA)
        shutil.move("PMATRX.merged", PMATRX_AA)
        shutil.move("output.flux_ufg", UFG_FLUX_EDIT)

        outputCache.cacheCall(
            cs["outputCacheLocation"],
            mc2v3,
            ["mc2v3-AB.inp"],
            ["ISOTXS.merged", "GAMISO.merged", "PMATRX.merged"],
        )
        shutil.move("ISOTXS.merged", ISOTXS_AB)
        shutil.move("GAMISO.merged", GAMISO_AB)
        shutil.move("PMATRX.merged", PMATRX_AB)

        # ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
        # ::                                                      ::
        # ::                     COMBINE                          ::
        # ::                                                      ::
        # ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

        outputCache.cacheCall(cs["outputCacheLocation"], mc2v3,
                              ["combine-AA-AB.inp"], ["ISOTXS.merged"])
        shutil.move("ISOTXS.merged", ISOTXS_AA_AB)

        outputCache.cacheCall(
            cs["outputCacheLocation"],
            mc2v3,
            ["combine-AA-AB.pmatrx.inp"],
            ["PMATRX.merged"],
        )
        shutil.move("PMATRX.merged", PMATRX_AA_AB)

        outputCache.cacheCall(
            cs["outputCacheLocation"],
            mc2v3,
            ["combine-AA-AB.gamiso.inp"],
            ["ISOTXS.merged"],
        )
        shutil.move("ISOTXS.merged", GAMISO_AA_AB)

        # ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
        # ::                                                      ::
        # ::                COMBINE AND LUMP                      ::
        # ::                                                      ::
        # ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

        subprocess.call([mc2v3, "combine-and-lump-AA-AB.inp"])
        shutil.move("ISOTXS.merged", ISOTXS_LUMPED)

        subprocess.call([mc2v3, "combine-and-lump-AA-AB.pmatrx.inp"])
        shutil.move("PMATRX.merged", PMATRX_LUMPED)

        subprocess.call([mc2v3, "combine-and-lump-AA-AB.gamiso.inp"])
        shutil.move("ISOTXS.merged", GAMISO_LUMPED)
Ejemplo n.º 24
0
    def setUpClass(cls):

        cls.directoryChanger = directoryChangers.DirectoryChanger(
            os.path.join(TEST_ROOT, "tutorials"))
        cls.directoryChanger.open()
Ejemplo n.º 25
0
 def test_change_to_nonexisting_fails(self):
     """Fail if destination doesn't exist."""
     with self.assertRaises(OSError):
         with directoryChangers.DirectoryChanger(self.temp_directory):
             pass
Ejemplo n.º 26
0
def fuelHandlerFactory(operator):
    """
    Return an instantiated FuelHandler object based on user settings.

    The FuelHandler is expected to be a short-lived object that only lives for
    the cycle upon which it acts. At the next cycle, this factory will be
    called again to instantiate a new FuelHandler.
    """
    cs = operator.cs
    fuelHandlerClassName = cs["fuelHandlerName"]
    fuelHandlerModulePath = cs["shuffleLogic"]

    if not fuelHandlerClassName:
        # User did not request a custom fuel handler.
        # This is code coupling that should be untangled.
        # Special case for equilibrium-mode shuffling
        if cs["eqDirect"] and cs["runType"].lower() == RunTypes.STANDARD.lower():
            from terrapower.physics.neutronics.equilibrium import fuelHandler as efh

            return efh.EqDirectFuelHandler(operator)
        else:
            # give the default FuelHandler. This does not have an implemented outage, but
            # still offers moving capabilities. Useful when you just need to make explicit
            # moves but do not have a fully-defined fuel management input.
            return fuelHandlers.FuelHandler(operator)

    # User did request a custom fuel handler. We must go find and import it
    # from the input directory.
    with directoryChangers.DirectoryChanger(cs.inputDirectory, dumpOnException=False):
        try:
            module = pathTools.importCustomPyModule(fuelHandlerModulePath)

            if not hasattr(module, fuelHandlerClassName):
                raise KeyError(
                    "The requested fuel handler object {0} is not "
                    "found in the fuel management input file {1} from CWD {2}. "
                    "Check input"
                    "".format(
                        fuelHandlerClassName, fuelHandlerModulePath, cs.inputDirectory
                    )
                )
            # instantiate the custom object
            fuelHandlerCls = getattr(module, fuelHandlerClassName)
            fuelHandler = fuelHandlerCls(operator)

            # also get getFactorList function from module level if it's there.
            # This is a legacy input option, getFactorList should now generally
            # be an method of the FuelHandler object
            if hasattr(module, "getFactorList"):
                # staticmethod binds the provided getFactorList function to the
                # fuelHandler object without passing the implicit self argument.
                # The __get__ pulls the actual function out from the descriptor.
                fuelHandler.getFactorList = staticmethod(module.getFactorList).__get__(
                    fuelHandlerCls
                )

        except IOError:
            raise ValueError(
                "Either the file specified in the `shuffleLogic` setting ({}) or the "
                "fuel handler class name specified in the `fuelHandlerName` setting ({}) "
                "cannot be found. CWD is: {}. Update input.".format(
                    fuelHandlerModulePath, fuelHandlerClassName, cs.inputDirectory
                )
            )
    return fuelHandler