Source code for esm_runscripts.yac

[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"