Source code for viperleed.calc.files.parameters.read

"""Module read of viperleed.calc.files.parameters.

Initial version by @fkraushofer in 2020, major rewrite by @amimre
and @michele-riva in June 2023. This module used to be part of
parameters.py. Refactored in October 2023.

Functions for reading from a PARAMETERS file and for updating
an Rparams object at runtime from a user-modified PARAMETERS file.
"""

__authors__ = (
    'Florian Kraushofer (@fkraushofer)',
    'Alexander M. Imre (@amimre)',
    'Michele Riva (@michele-riva)',
    )
__copyright__ = 'Copyright (c) 2019-2024 ViPErLEED developers'
__created__ = '2020-08-18'
__license__ = 'GPLv3+'

import logging
from pathlib import Path

from viperleed.calc.classes import rparams
from viperleed.calc.lib.base import parent_name

from .errors import MissingEqualsError
from .interpret import ParameterInterpreter
from .reader import ParametersReader
from .write import comment_out


_LOGGER = logging.getLogger(parent_name(__name__))


[docs]def read(filename='PARAMETERS'): """Return an Rparams with the raw contents read from a PARAMETERS file. Parameters ---------- filename : str or Path, optional The file to be read. The default is 'PARAMETERS'. Returns ------- rpars : Rparams Object storing parameters for current run. Contains the raw parameters read in this function in its `.readParams` attribute. The parameters read are not interpreted. For that, call `parameters.interpret` passing the the same `rpars` object. Raises ------ FileNotFoundError If filename does not exist. ParameterNotRecognizedError If one of the parameters read from filename is not a known one, or if a parameter read has no value. """ filename = Path(filename).resolve() if not filename.is_file(): _LOGGER.error('PARAMETERS file not found.') raise FileNotFoundError(filename) rpars = rparams.Rparams() comment_out_stop = False with ParametersReader(filename, noisy=True) as param_file: while True: try: param, assignment = next(param_file) except StopIteration: break except MissingEqualsError as exc: _LOGGER.warning(exc) rpars.setHaltingLevel(2) continue if param == 'STOP': comment_out_stop = True else: rpars.readParams[param].append(assignment) if comment_out_stop: _LOGGER.warning( 'PARAMETERS file: STOP was set at start of ' 'program. Modifying PARAMETERS to disable STOP; ' 're-insert it if you actually want to stop.' ) comment_out(rpars, 'STOP', comment='Disabled at program start', path=filename.parent, suppress_ori=True) return rpars
def update(rpars, filename='PARAMETERS', update_from=''): """Update `rpars` from file. The following parameters are considered: SEARCH_CONVERGENCE, STOP (and its legacy names). Parameters ---------- rpars : Rparams Parameters for current run. Its attributes are updated if the contents of `filename` has changed. filename : str or Path, optional The file to be read. The default is 'PARAMETERS'. update_from : str or Path, optional Path to the directory in which to look for `filename`. The default is an empty string, corresponding to the current directory. Raises ------ FileNotFoundError If no `filename` is found in `update_from`. ParameterError If one of the parameters to be updated has an invalid value. """ filename = Path(update_from, filename).resolve() if not filename.is_file(): _LOGGER.error('parameters.update: PARAMETERS file not found.') raise FileNotFoundError(filename) # Note that no slab is given to the interpreter. It is not needed # for STOP (+legacy names) and SEARCH_CONVERGENCE. Also, note that # we don't complain (again) about faulty parameters while reading interpreter = ParameterInterpreter(rpars) with ParametersReader(filename, noisy=False) as param_file: for param, assignment in param_file: if param == 'STOP': # pylint: disable=no-member # Method is added dynamically interpreter.interpret_stop(assignment) if rpars.STOP: return # No need to continue reading if param == 'SEARCH_CONVERGENCE': interpreter.interpret_search_convergence(assignment=assignment, is_updating=True)