def read_amrvac_namelist(parfiles): """Read one or more parfiles, and return a unified f90nml.Namelist object. This function replicates the patching logic of MPI-AMRVAC where redundant parameters only retain last-in-line values, with the exception of `&filelist:base_filename`, which is accumulated. When passed a single file, this function acts as a mere wrapper of f90nml.read(). Parameters ---------- parfiles : str, os.Pathlike, byte, or an iterable returning those types A file path, or a list of file paths to MPI-AMRVAC configuration parfiles. Returns ------- unified_namelist : f90nml.Namelist A single namelist object. The class inherits from ordereddict. """ parfiles = (os.path.expanduser(pf) for pf in always_iterable(parfiles)) # first merge the namelists namelists = [f90nml.read(parfile) for parfile in parfiles] unified_namelist = f90nml.Namelist() for nml in namelists: unified_namelist.patch(nml) # accumulate `&filelist:base_filename` base_filename = "".join( nml.get("filelist", {}).get("base_filename", "") for nml in namelists) unified_namelist["filelist"]["base_filename"] = base_filename return unified_namelist
def test_namelist_reading(): ds = data_dir_load(ramses_new_format) namelist_fname = os.path.join(ds.directory, 'namelist.txt') with open(namelist_fname, 'r') as f: ref = f90nml.read(f) nml = ds.parameters['namelist'] assert nml == ref
def test_accumulate_basename(): """When two (or more) parfiles are passed, the filelist:base_filename should be special-cased""" namelist_base = f90nml.read(blast_wave_parfile) namelist_update = f90nml.read(modifier_parfile) namelist_tot1 = read_amrvac_namelist([blast_wave_parfile, modifier_parfile]) namelist_tot2 = deepcopy(namelist_base) namelist_tot2.patch(namelist_update) # remove and store the special-case value name1 = namelist_tot1["filelist"].pop("base_filename") name2 = namelist_tot2["filelist"].pop("base_filename") assert name1 == namelist_base["filelist"]["base_filename"] + namelist_update["filelist"]["base_filename"] assert name2 == namelist_update["filelist"]["base_filename"] assert name1 != name2 # test equality for the rest of the namelist assert namelist_tot1 == namelist_tot2
def read_namelist(self): """Read the namelist.txt file in the output folder, if present""" namelist_file = os.path.join(self.root_folder, 'namelist.txt') if os.path.exists(namelist_file): try: with open(namelist_file, 'r') as f: nml = f90nml.read(f) except ImportError as e: nml = "An error occurred when reading the namelist: %s" % str(e) except ValueError as e: mylog.warn("Could not parse `namelist.txt` file as it was malformed: %s" % str(e)) return self.parameters['namelist'] = nml
def read_namelist(self): """Read the namelist.txt file in the output folder, if present""" namelist_file = os.path.join(self.root_folder, "namelist.txt") if os.path.exists(namelist_file): try: with open(namelist_file, "r") as f: nml = f90nml.read(f) except ImportError as e: nml = f"An error occurred when reading the namelist: {str(e)}" except (ValueError, StopIteration) as e: mylog.warning( "Could not parse `namelist.txt` file as it was malformed: %s", e) return self.parameters["namelist"] = nml
def read_amrvac_namelist(parfiles): """Read one or more parfiles, and return a unified f90nml.Namelist object. This function replicates the patching logic of MPI-AMRVAC where redundant parameters only retain last-in-line values EXCEPT `&filelist:base_filename`, which is accumulated. When passed a single file, this function acts as a mere wrapper of f90nml.read(). Parameters ---------- parfiles : str or list A file path, or a list of file paths to MPI-AMRVAC configuration parfiles. Returns ------- unified_namelist : f90nml.Namelist A single namelist object. The class inherits from ordereddict. """ # typechecking if isinstance(parfiles, string_types): parfiles = [parfiles] assert all([isinstance(pf, string_types) for pf in parfiles]) # first merge the namelists namelists = [f90nml.read(parfile) for parfile in parfiles] unified_namelist = f90nml.Namelist() for nml in namelists: unified_namelist.patch(nml) # accumulate `&filelist:base_filename` base_filename = "".join([ nml.get("filelist", {}).get("base_filename", "") for nml in namelists ]) unified_namelist["filelist"]["base_filename"] = base_filename return unified_namelist
def read_amrvac_namelist(parfiles): """Read one or more parfiles, and return a unified f90nml.Namelist object. This function replicates the patching logic of MPI-AMRVAC where redundant parameters only retain last-in-line values EXCEPT `&filelist:base_filename`, which is accumulated. """ # typechecking if isinstance(parfiles, string_types): parfiles = [parfiles] assert all([isinstance(pf, string_types) for pf in parfiles]) # first merge the namelists namelists = [f90nml.read(parfile) for parfile in parfiles] unified_namelist = f90nml.Namelist() for nml in namelists: unified_namelist.patch(nml) # accumulate `&filelist:base_filename` base_filename = "".join([ nml.get("filelist", {}).get("base_filename", "") for nml in namelists ]) unified_namelist["filelist"]["base_filename"] = base_filename return unified_namelist
def test_read_one_file(): """when provided a single file, the function should merely act as a wrapper for f90nml.read()""" namelist1 = read_amrvac_namelist(blast_wave_parfile) namelist2 = f90nml.read(blast_wave_parfile) assert namelist1 == namelist2