[docs]class yac:
"""
Generates the configuration file for YAC coupler.
"""
def __init__(self, full_config, nb_of_couplings=1, coupled_models=["echam", "fesom"], grids=["atmo", "feom"], runtime=1):
self.name = "yac"
self.namcouple = ['<?xml version="1.0" encoding="UTF-8"?>']
self.namcouple += ["<!-- This coupling.xml was automatically generated by the esm-tools (Python) -->"]
self.namcouple += ["<coupling"]
self.namcouple += ['\txmlns="http://www.w3schools.com"']
self.namcouple += ['\txmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"']
self.namcouple += ['\txsi:schemaLocation="http://www.w3schools.com coupling.xsd">']
self.namcouple += ['\t<redirect redirect_of_root="' + str(full_config[self.name]['redirect_of_root']).lower() + '" redirect_stdout="' + str(full_config[self.name]['redirect_stdout']).lower() + '"/>']
self.namcouple += ['\t<components>']
component_id = 1
for component in full_config[self.name]["component_names"]:
self.namcouple += ['\t\t<component id="' + str(component_id) + '">']
self.namcouple += ['\t\t\t<name>' + str(component) + '</name>']
self.namcouple += ['\t\t\t<model>' + str(component) + '</model>']
self.namcouple += ['\t\t\t<simulated>' + str(full_config[coupled_models[component_id - 1]]["type"]) + '</simulated>']
self.namcouple += ['\t\t\t<transient_grid_refs>']
for field in range(nb_of_couplings):
self.namcouple += ['\t\t\t\t<transient_grid_ref id="' + str(field + 1) + '" transient_ref="' + str(field + 1) + '" grid_ref="' + str(component_id) + '" collection_size="1"/>']
self.namcouple += ['\t\t\t</transient_grid_refs>']
self.namcouple += ['\t\t</component>']
component_id += 1
self.namcouple += ['\t</components>']
self.namcouple += ['\t<transients>']
for field in range(nb_of_couplings):
self.namcouple += ['\t\t<transient id="' + str(field + 1) + '" transient_standard_name="??transient_name' + str(field + 1) + '??"/>'] # Placeholder ??..?? will be replace further down.
self.namcouple += ['\t</transients>']
self.namcouple += ['\t<grids>']
grid_id = 1
for grid in grids:
self.namcouple += ['\t\t<grid id="' + str(grid_id) + '" alias_name="' + str(grid) + '" />']
grid_id += 1
self.namcouple += ['\t</grids>']
self.namcouple += ['\t<dates>']
self.namcouple += ['\t\t\t<start_date>' + str(full_config["general"]['initial_date']) + '</start_date>']
self.namcouple += ['\t\t\t<end_date>' + str(full_config["general"]['next_date']) + '</end_date>']
self.namcouple += ['\t\t\t<calendar>' + str(full_config[self.name]['calendar']) + '</calendar>']
self.namcouple += ['\t</dates>']
self.namcouple += ['\t<timestep_unit>' + str(full_config[self.name]['coupling_time_step_unit']) + '</timestep_unit>']
self.namcouple += ["\t<couples>"]
self.namcouple += ['\t\t<couple>']
component_id = 1
for component in coupled_models:
self.namcouple += ['\t\t\t<component' + str(component_id) + ' component_id="' + str(component_id) + '" />']
component_id += 1
self.next_coupling = 1
[docs] def add_coupling(self, field, transient_id, direction, config):
import sys
coupling_field = field.replace("<--", "%").replace("--", "&")
source, rest = coupling_field.split("%")
source = source.strip()
interpolation, target = rest.split("&")
target = target.strip()
interpolation = interpolation.strip()
# Replacing placeholder ??..?? with field keyname source
matching = [s for s in self.namcouple if "??transient_name" + str(transient_id) + "??" in s]
index = self.namcouple.index(matching[0])
self.namcouple[index] = self.namcouple[index].replace("??transient_name" + str(transient_id) + "??", source)
self.namcouple += ['\t\t\t\t<transient_couple transient_id="' + str(transient_id) + '">']
self.namcouple += ['\t\t\t\t\t<source component_ref="' + str(config["coupling_directions"][direction]["source"]["component_id"]) + '" transient_grid_ref="' + str(transient_id) + '" />']
self.namcouple += ['\t\t\t\t\t<target transient_grid_ref="' + str(transient_id) + '" />']
self.namcouple += ['\t\t\t\t\t<timestep>']
self.namcouple += ['\t\t\t\t\t\t<source>' + str(config["coupling_directions"][direction]["source"]["timestep"]) + '</source>']
self.namcouple += ['\t\t\t\t\t\t<target>' + str(config["coupling_directions"][direction]["target"]["timestep"]) + '</target>']
self.namcouple += ['\t\t\t\t\t\t<coupling_period operation="' + str(config["coupling_directions"][direction]["operation"]) + '">' + str(config["coupling_time_step"]) + '</coupling_period>']
self.namcouple += ['\t\t\t\t\t\t<source_timelag>' + str(config["coupling_directions"][direction]["source"]["timelag"]) + '</source_timelag>']
self.namcouple += ['\t\t\t\t\t\t<target_timelag>' + str(config["coupling_directions"][direction]["target"]["timelag"]) + '</target_timelag>']
self.namcouple += ['\t\t\t\t\t</timestep>']
self.namcouple += ['\t\t\t\t\t<interpolation_requirements use_source_mask="' + str(config["coupling_directions"][direction]["source"]["use_mask"]).lower() + '" use_target_mask="' + str(config["coupling_directions"][direction]["source"]["use_mask"]).lower() + '">']
line = '<interpolation method="' + str(interpolation) + '" '
for option in config["interpolation_methods"][interpolation]["options"]:
value = config["interpolation_methods"][interpolation]["options"][option]
line += ' ' + str(option) + ' ="' + str(value) + '"'
line += '/>'
self.namcouple += ['\t\t\t\t\t\t\t' + line]
self.namcouple += ['\t\t\t\t\t</interpolation_requirements>']
self.namcouple += ['\t\t\t\t\t<debug_mode at_source_before_interpolation="' + str(config["coupling_directions"][direction]["source"]["debug_before_interpolation"]).lower() + '" at_source_after_interpolation="' + str(config["coupling_directions"][direction]["source"]["debug_before_interpolation"]).lower() + '" at_target="' + str(config["coupling_directions"][direction]["target"]["debug"]).lower() + '"/>']
self.namcouple += ['\t\t\t\t\t<enforce_write_restart>' + str(config["coupling_directions"][direction]["write_restart"]).lower() + '</enforce_write_restart>']
self.namcouple += ['\t\t\t\t\t<enforce_write_weight_file filename="' + str(source) + '_weight">' + str(config["coupling_directions"][direction]["write_weight"]).lower() + '</enforce_write_weight_file>']
self.namcouple += ['\t\t\t\t</transient_couple>']
[docs] def print_config_files(self):
for line in self.namcouple:
print(line)
[docs] def add_output_file(self, lefts, rights, leftmodel, rightmodel, config):
out_file = []
coupling = self.next_coupling
if self.next_coupling < 10:
this_coupling = "0" + str(coupling)
else:
this_coupling = str(coupling)
for lefty in lefts:
out_file.append(lefty + "_" + leftmodel + "_" + this_coupling + ".nc")
for righty in rights:
out_file.append(righty + "_" + rightmodel + "_" + this_coupling + ".nc")
self.next_coupling += 1
if "outdata_files" not in config:
config["outdata_files"] = {}
if "outdata_in_work" not in config:
config["outdata_in_work"] = {}
if "outdata_sources" not in config:
config["outdata_sources"] = {}
for thisfile in out_file:
config["outdata_files"][thisfile] = thisfile
config["outdata_in_work"][thisfile] = thisfile
config["outdata_sources"][thisfile] = thisfile
[docs] def add_restart_files(self, restart_file, fconfig):
config = fconfig[self.name]
gconfig = fconfig["general"]
# enddate = "_" + str(gconfig["end_date"].year) + str(gconfig["end_date"].month) + str(gconfig["end_date"].day)
# parentdate = "_" + str(config["parent_date"].year) + str(config["parent_date"].month) + str(config["parent_date"].day)
enddate = "_" + gconfig["end_date"].format(
form=9, givenph=False, givenpm=False, givenps=False
)
parentdate = "_" + config["parent_date"].format(
form=9, givenph=False, givenpm=False, givenps=False
)
if "restart_out_files" not in config:
config["restart_out_files"] = {}
if "restart_out_in_work" not in config:
config["restart_out_in_work"] = {}
if "restart_out_sources" not in config:
config["restart_out_sources"] = {}
if "restart_in_files" not in config:
config["restart_in_files"] = {}
if "restart_in_in_work" not in config:
config["restart_in_in_work"] = {}
if "restart_in_sources" not in config:
config["restart_in_sources"] = {}
config["restart_out_files"][restart_file] = restart_file
config["restart_out_files"][restart_file + "_recv"] = restart_file + "_recv"
config["restart_out_in_work"][restart_file] = restart_file # + enddate
config["restart_out_in_work"][restart_file + "_recv"] = restart_file + "_recv" # + enddate
config["restart_out_sources"][restart_file] = restart_file
config["restart_out_sources"][restart_file + "_recv"] = restart_file + "_recv"
config["restart_in_files"][restart_file] = restart_file
config["restart_in_in_work"][restart_file] = restart_file
if restart_file not in config["restart_in_sources"]:
config["restart_in_sources"][restart_file] = restart_file
[docs] def prepare_restarts(self, restart_file, all_fields, model, config):
enddate = "_" + config["general"]["end_date"].format(
form=9, givenph=False, givenpm=False, givenps=False
)
# enddate = "_" + str(config["general"]["end_date"].year) + str(config["general"]["end_date"].month) + str(config["general"]["end_date"].day)
import glob
import os
import subprocess
print("Preparing YAC restart files from initial run...")
exe = config[model]["executable"]
print(restart_file, all_fields, model, exe)
cwd = os.getcwd()
os.chdir(config["general"]["thisrun_work_dir"])
filelist = ""
for field in all_fields:
print(field + "-" + model)
thesefiles = glob.glob(field + "_" + exe + "_*.nc")
print(thesefiles)
for thisfile in thesefiles:
print("cdo showtime " + thisfile + " 2>/dev/null | wc -w")
lasttimestep = subprocess.check_output("cdo showtime " + thisfile + " 2>/dev/null | wc -w", shell=True).decode("utf-8").rstrip()
# print (lasttimestep)
print("cdo -O seltimestep," + str(lasttimestep) + " " + thisfile + " onlyonetimestep.nc")
os.system("cdo -O seltimestep," + str(lasttimestep) + " " + thisfile + " onlyonetimestep.nc")
print("ncwa -O -a time onlyonetimestep.nc notimestep_" + field + ".nc")
os.system("ncwa -O -a time onlyonetimestep.nc notimestep_" + field + ".nc")
filelist += "notimestep_" + field + ".nc "
print(filelist)
print("cdo merge " + filelist + " " + restart_file) # + enddate)
os.system("cdo merge " + filelist + " " + restart_file) # + enddate)
rmlist = glob.glob("notimestep*")
rmlist.append("onlyonetimestep.nc")
for rmfile in rmlist:
print("rm " + rmfile)
os.system("rm " + rmfile)
os.chdir(cwd)
[docs] def finalize(self, destination_dir):
self.namcouple += ["\t\t</couple>"]
self.namcouple += ["\t</couples>"]
self.namcouple += ["</coupling>"]
endline = ""
with open(destination_dir + "/coupling.xml", "w") as namcouple:
for line in self.namcouple:
namcouple.write(endline)
namcouple.write(line)
endline = "\n"