diff --git a/cases/cosmo-ghg-spinup-test/cosmo_runjob.cfg b/cases/cosmo-ghg-spinup-test/cosmo_runjob.cfg index 28c0cbb6..608b8d15 100644 --- a/cases/cosmo-ghg-spinup-test/cosmo_runjob.cfg +++ b/cases/cosmo-ghg-spinup-test/cosmo_runjob.cfg @@ -34,7 +34,7 @@ echo "============== StartTime: `date +%s` s" echo "============== StartTime: `date`" echo "=====================================================" -srun -u ./{execname} >> {logfile} 2>&1 +srun -u ./{cfg.cosmo_execname} >> {logfile} 2>&1 pid=$? echo "=====================================================" diff --git a/cases/cosmo-ghg-test/cosmo_runjob.cfg b/cases/cosmo-ghg-test/cosmo_runjob.cfg index 28c0cbb6..608b8d15 100644 --- a/cases/cosmo-ghg-test/cosmo_runjob.cfg +++ b/cases/cosmo-ghg-test/cosmo_runjob.cfg @@ -34,7 +34,7 @@ echo "============== StartTime: `date +%s` s" echo "============== StartTime: `date`" echo "=====================================================" -srun -u ./{execname} >> {logfile} 2>&1 +srun -u ./{cfg.cosmo_execname} >> {logfile} 2>&1 pid=$? echo "=====================================================" diff --git a/cases/icon-art-global-test/icon_runjob.cfg b/cases/icon-art-global-test/icon_runjob.cfg index 99b0de5e..d241a8cf 100644 --- a/cases/icon-art-global-test/icon_runjob.cfg +++ b/cases/icon-art-global-test/icon_runjob.cfg @@ -396,4 +396,4 @@ handle_error(){{ exit 1 fi }} -srun ./icon.exe || handle_error +srun ./{cfg.icon_execname} || handle_error diff --git a/cases/icon-art-oem-test/icon_runjob.cfg b/cases/icon-art-oem-test/icon_runjob.cfg index eec72b77..883c8d86 100644 --- a/cases/icon-art-oem-test/icon_runjob.cfg +++ b/cases/icon-art-oem-test/icon_runjob.cfg @@ -376,4 +376,4 @@ handle_error(){{ exit 1 fi }} -srun ./icon.exe || handle_error +srun ./{cfg.icon_execname} || handle_error diff --git a/cases/icon-test/icon_runjob.cfg b/cases/icon-test/icon_runjob.cfg index 07fabaaf..88c8b735 100755 --- a/cases/icon-test/icon_runjob.cfg +++ b/cases/icon-test/icon_runjob.cfg @@ -342,4 +342,4 @@ EOF # ---------------------------------------------------------------------- # run the model! # ---------------------------------------------------------------------- - srun ./icon.exe +srun ./{cfg.icon_execname} || handle_error diff --git a/config.py b/config.py index 188893dc..a984536f 100644 --- a/config.py +++ b/config.py @@ -319,24 +319,6 @@ def create_vars_from_dicts(self, dct=None, key=None): else: setattr(self, subkey, v) - def format_duration(self, duration): - """ - Format a duration represented by a datetime.timedelta object into a human-readable string. - - Parameters: - - duration (datetime.timedelta): The duration to be formatted. - - Returns: - - str: A string representing the formatted duration in the "0d 0h 0m 0s" format. - """ - seconds = duration.total_seconds() - days, remainder = divmod(seconds, 86400) - hours, remainder = divmod(remainder, 3600) - minutes, seconds = divmod(remainder, 60) - - formatted_duration = f"{int(days)}d {int(hours)}h {int(minutes)}m {int(seconds)}s" - return formatted_duration - def get_chunk_list(self): self.chunk_list = [] for startdate_sim in tools.iter_hours(self.startdate, self.enddate, @@ -359,7 +341,7 @@ def get_chunk_list(self): self.chunk_list.append(chunk_id) def get_previous_chunk_id(self, current_chunk_id): - """Get the previous chunk ID based on the current chunk ID.""" + """Get the previous chunk ID based on the current `chunk_id`""" index = self.chunk_list.index(current_chunk_id) if index > 0: self.chunk_id_prev = self.chunk_list[index - 1] @@ -381,33 +363,26 @@ def get_dep_ids(self, job_name, add_dep=None): dep_id_list = [] # Add job dependencies - if not self.force_sync: - # Could be that job has no dependency, even in an async config, - # e.g., prepare_data - if deps := self.workflow['dependencies'].get(job_name): - for stage in 'previous', 'current': - if dep_stage := deps.get(stage): - for job in dep_stage: - # Could be that dep job id does not exist, e.g., - # if dep job is deactivated or it's the first chunk - if dep_id := self.job_ids[stage].get(job): - dep_id_list.extend(dep_id) + if deps := self.workflow['dependencies'].get(job_name): + for stage in 'previous', 'current': + if dep_stage := deps.get(stage): + for job in dep_stage: + # Could be that dep job id does not exist, e.g., + # if dep job is deactivated or it's the first chunk + if dep_id := self.job_ids[stage].get(job): + dep_id_list.extend(dep_id) return dep_id_list def get_dep_cmd(self, job_name, add_dep=None): - """Generate the part of the sbatch command that sepcifies dependencies for job_name.""" - if not self.force_sync: - # Default: async case - if dep_ids := self.get_dep_ids(job_name, add_dep=add_dep): - dep_str = ':'.join(map(str, dep_ids)) - return f'--dependency=afterok:{dep_str}' - else: - # job_name has no dependencies but still belongs to an async workflow - # so don't use --wait - return None + """Generate the part of the sbatch command that sepcifies dependencies for `job_name`""" + # Default: async case + if dep_ids := self.get_dep_ids(job_name, add_dep=add_dep): + dep_str = ':'.join(map(str, dep_ids)) + return f'--dependency=afterok:{dep_str}' else: - # Needed for nested run_chain.py - return '--wait' + # job_name has no dependencies but still belongs to an async workflow + # so don't use --wait + return None def submit(self, job_name, script, add_dep=None): """Submit job with dependencies""" diff --git a/jobs/cosmo.py b/jobs/cosmo.py index 1afdca96..fae8f9a8 100644 --- a/jobs/cosmo.py +++ b/jobs/cosmo.py @@ -14,28 +14,20 @@ def main(cfg): - """Setup the namelists for a COSMO tracer run and submit the job to the queue. - - Necessary for both COSMO and COSMOART simulations. - - Decide if the soil model should be TERRA or TERRA multi-layer depending on - the ``startdate`` of the simulation. + """Setup the namelists for a COSMO run and submit the job to the queue. Create necessary directory structure to run COSMO (run, output, and restart directories, defined in ``cfg.cosmo_run``, ``cfg.cosmo_output``, and ``cfg.cosmo_restart_out``). Copy the COSMO-executable from - ``cfg.cosmo_bin`` to ``cfg.cosmo_run/cosmo``. + ``cfg.cosmo['binary_file']`` to ``cfg.cosmo_run/cfg.cosmo['execname']``. - Convert the tracer-csv-file to a COSMO-namelist file. + Convert the tracer csv file to a COSMO namelist file. - Format the COSMO-namelist-templates - (COSMO: ``AF,ORG,IO,DYN,PHY,DIA,ASS``, - COSMOART: ``ART,ASS,DIA,DYN,EPS,INI,IO,ORG,PHY``) - using the information in ``cfg``. + Format the COSMO namelist templates using the information in ``cfg``. - Format the runscript-template and submit the job. + Format the runscript template and submit the job. Parameters ---------- @@ -128,9 +120,8 @@ def main(cfg): tools.create_dir(cfg.cosmo_restart_out, "cosmo_restart_out") # Copy cosmo executable - cfg.cosmo['execname'] = 'cosmo.exe' - tools.copy_file(cfg.cosmo['binary_file'], - os.path.join(cfg.cosmo_run, cfg.cosmo['execname'])) + cfg.cosmo_execname = Path(cfg.cosmo['binary_file']) + tools.copy_file(cfg.cosmo['binary_file'], cfg.cosmo_run / cfg.cosmo_execname) # Prepare namelist and submit job tracer_csvfile = os.path.join(cfg.chain_src_dir, 'cases', cfg.casename, diff --git a/jobs/icon.py b/jobs/icon.py index 393f740e..e0bce669 100644 --- a/jobs/icon.py +++ b/jobs/icon.py @@ -2,26 +2,19 @@ # -*- coding: utf-8 -*- import logging +from pathlib import Path from . import tools, prepare_icon BASIC_PYTHON_JOB = False def main(cfg): - """Setup the namelists for an ICON tracer run and submit the job to + """Setup the namelists for an ICON run and submit the job to the queue. - Necessary for both ICON and ICONART simulations. - - Create necessary directory structure to run ICON (run, output, and - restart directories, defined in ``cfg.icon_work``, ``cfg.icon_output``, - and ``cfg.icon_restart_out``). - Copy the ICON-executable from ``cfg.icon_binary_file`` to ``cfg.icon_work/icon.exe``. - Use the tracer-csv-file to append ICON-namelist file. - Format the ICON-namelist-templates: ``icon_master.namelist.cfg, icon_NAMELIST_NWP.cfg``, using the information in ``cfg``. @@ -40,9 +33,9 @@ def main(cfg): "submit the job to the queue") # Copy icon executable - execname = 'icon.exe' + cfg.icon_execname = Path(cfg.icon['binary_file']) tools.create_dir(cfg.icon_work, "icon_work") - tools.copy_file(cfg.icon_binary_file, cfg.icon_work / execname) + tools.copy_file(cfg.icon_binary_file, cfg.icon_work / cfg.icon_execname) # Symlink the restart file to the last run into the icon/run folder if cfg.lrestart == '.TRUE.': diff --git a/run_chain.py b/run_chain.py index 02b49950..70384f52 100755 --- a/run_chain.py +++ b/run_chain.py @@ -351,7 +351,7 @@ def main(): print("╔════════════════════════════════════════╗") print("║ Starting Processing Chain ║") - print("║════════════════════════════════════════║") + print("╠════════════════════════════════════════╣") print(f"║ Case: {casename: <27} ║") print(f"║ Workflow: {cfg.workflow_name: <27} ║") print("╚════════════════════════════════════════╝")