[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 not "outdata_files" in config:
config["outdata_files"] = {}
if not "outdata_in_work" in config:
config["outdata_in_work"] = {}
if not "outdata_sources" 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 not "restart_out_files" in config:
config["restart_out_files"] = {}
if not "restart_out_in_work" in config:
config["restart_out_in_work"] = {}
if not "restart_out_sources" in config:
config["restart_out_sources"] = {}
if not "restart_in_files" in config:
config["restart_in_files"] = {}
if not "restart_in_in_work" in config:
config["restart_in_in_work"] = {}
if not "restart_in_sources" 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 not restart_file 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"