Skip to content

Commit 6a2e88e

Browse files
Refactor wet model drivers and controllers
Co-authored-by: harry-shepherd <17930806+harry-shepherd@users.noreply.github.com>
1 parent 5d06530 commit 6a2e88e

11 files changed

Lines changed: 359 additions & 1154 deletions

File tree

Coupled_Drivers/common.py

Lines changed: 33 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
#!/usr/bin/env python3
1+
#!/usr/bin/env python
22
'''
33
*****************************COPYRIGHT******************************
4-
(C) Crown copyright 2022-2025 Met Office. All rights reserved.
4+
(C) Crown copyright 2021 Met Office. All rights reserved.
55
66
Use, duplication or disclosure of this code is subject to the restrictions
77
as set forth in the licence. If no licence has been raised with this copy
@@ -18,11 +18,9 @@
1818
Common functions and classes required by multiple model drivers
1919
'''
2020

21-
22-
23-
import datetime
24-
import glob
25-
import shutil
21+
#The from __future__ imports ensure compatibility between python2.7 and 3.x
22+
from __future__ import absolute_import
23+
import copy
2624
import re
2725
import os
2826
import sys
@@ -32,7 +30,6 @@
3230
import error
3331
import inc_days
3432

35-
3633
class ModNamelist(object):
3734
'''
3835
Modify a fortran namelist. This will not add any new variables, only
@@ -49,7 +46,7 @@ def __init__(self, filename):
4946
def var_val(self, variable, value):
5047
'''
5148
Create a container of variable name, value pairs to be updated. Note
52-
that if a variable doesn't exist in the namelist file, then it
49+
that if a variable doesn't exisit in the namelist file, then it
5350
will be ignored
5451
'''
5552
if isinstance(value, str):
@@ -83,7 +80,7 @@ def find_previous_workdir(cyclepoint, workdir, taskname, task_param_run=None):
8380
'''
8481
Find the work directory for the previous cycle. Takes as argument
8582
the current cyclepoint, the path to the current work directory, and
86-
the current taskname, a value specifying multiple tasks within
83+
the current taskname, a value specifying multiple tasks within
8784
same cycle (e.g. coupled_run1, coupled_run2) as used in coupled NWP
8885
and returns an absolute path.
8986
'''
@@ -100,7 +97,7 @@ def find_previous_workdir(cyclepoint, workdir, taskname, task_param_run=None):
10097

10198
return previous_workdir
10299

103-
else:
100+
else:
104101
cyclesdir = os.sep.join(workdir.split(os.sep)[:-2])
105102
#find the work directory for the previous cycle
106103
work_cycles = os.listdir(cyclesdir)
@@ -121,7 +118,7 @@ def find_previous_workdir(cyclepoint, workdir, taskname, task_param_run=None):
121118
sys.stderr.write('[FAIL] Can not find previous work directory for'
122119
' task %s\n' % taskname)
123120
sys.exit(error.MISSING_DRIVER_FILE_ERROR)
124-
121+
125122
return os.path.join(cyclesdir, previous_task_cycle, taskname)
126123

127124

@@ -139,6 +136,7 @@ def get_filepaths(directory):
139136
return file_paths
140137

141138

139+
142140
def open_text_file(name, mode):
143141
'''
144142
Provide a common function to open a file and provide a suitiable error
@@ -152,7 +150,7 @@ def open_text_file(name, mode):
152150
'a+':'updating (appending)'}
153151
if mode not in list(modes.keys()):
154152
options = ''
155-
for k in modes:
153+
for k in modes.keys():
156154
options += ' %s: %s\n' % (k, modes[k])
157155
sys.stderr.write('[FAIL] Attempting to open file %s, do not recognise'
158156
' mode %s. Please use one of the following modes:\n%s'
@@ -188,6 +186,28 @@ def remove_file(filename):
188186
else:
189187
return False
190188

189+
def remove_trailing_slash(path_str):
190+
'''
191+
Takes a string of a path and removes any trailing slashes and spaces if
192+
there are any present
193+
'''
194+
trailing_slash_regex = r'[\w/]*\w+([\s/]+)$'
195+
match = re.match(trailing_slash_regex, path_str)
196+
if match:
197+
num_trailing_slashes = len(match.group(1))
198+
return path_str[:-num_trailing_slashes]
199+
return path_str
200+
201+
202+
def remove_trailing_slash_orig(path_str):
203+
'''
204+
Takes a string of a path and removes the trailing slash if there is one
205+
present
206+
'''
207+
if path_str[-1] == '/':
208+
return path_str[:-1]
209+
return path_str
210+
191211
def setup_runtime(common_env):
192212
'''
193213
Set up model run length in seconds based on the model suite
@@ -324,53 +344,3 @@ def set_aprun_options(nproc, nodes, ompthr, hyperthreads, ss):
324344
rose_launcher_preopts = "-ss " + rose_launcher_preopts
325345

326346
return rose_launcher_preopts
327-
328-
329-
def _sort_hist_dirs_by_date(dir_list):
330-
'''
331-
Sort a list of history directories by date
332-
'''
333-
# Pattern that defines the name of the history directories,
334-
# which contain a date of the form YYYYmmddHHMM.
335-
pattern = r'\.(\d{12})'
336-
337-
try:
338-
dir_list.sort(key=lambda dname: datetime.datetime.strptime(
339-
re.search(pattern, dname).group(1), '%Y%m%d%H%M'))
340-
except AttributeError:
341-
msg = '[FAIL] Cannot order directories: %s' % " ".join(dir_list)
342-
sys.stderr.write(msg)
343-
sys.exit(error.IOERROR)
344-
345-
return dir_list
346-
347-
348-
def remove_latest_hist_dir(old_hist_dir):
349-
'''
350-
If a model task has failed, then removed the last created history
351-
directory, before a new one is created, associated with the
352-
re-attempt.
353-
'''
354-
# Replace the regex pattern that defines the history directory
355-
# name (that contains a date of the format YYYYmmddHHMM) with a
356-
# generic pattern so that we can perform the directory glob.
357-
history_pattern = re.sub(
358-
r'\.\d{12}', '.????????????', old_hist_dir)
359-
360-
# Find and sort the history directories, and delete
361-
# the latest one, corresponding to the last entry in
362-
# the list.
363-
history_dirs = glob.glob(history_pattern)
364-
history_dirs = _sort_hist_dirs_by_date(history_dirs)
365-
366-
msg = '[INFO] Found history directories: %s \n' % ' '.join(
367-
history_dirs)
368-
sys.stdout.write(msg)
369-
370-
latest_hist_dir = history_dirs[-1]
371-
msg = ("[WARN] Re-attempting failed model step. \n"
372-
"[WARN] Clearing out latest history \n"
373-
"[WARN] directory %s. \n" % latest_hist_dir)
374-
sys.stdout.write(msg)
375-
376-
shutil.rmtree(latest_hist_dir)

Coupled_Drivers/dr_env_lib/nemo_def.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
#!/usr/bin/env python3
1+
#!/usr/bin/env python
22
'''
33
*****************************COPYRIGHT******************************
4-
(C) Crown copyright 2021-2025 Met Office. All rights reserved.
4+
(C) Crown copyright 2021 Met Office. All rights reserved.
55
66
Use, duplication or disclosure of this code is subject to the restrictions
77
as set forth in the licence. If no licence has been raised with this copy
@@ -22,18 +22,20 @@
2222
# Variables required for both initalise and finalise
2323
NEMO_ENVIRONMENT_VARS_COMMON = {
2424
'NEMO_NL': {'default_val': 'namelist_cfg'},
25-
'L_OCN_PASS_TRC': {'default_val': 'false'}
25+
'L_OCN_PASS_TRC': {'default_val': 'false'},
26+
'NEMO_NPROC': {'desc': 'Number of NEMO processors'},
27+
'RST_LINK_DIR': {'default_val': '.',
28+
'desc': 'Subdirectory of $CYCL_TASK_WORK_DIR containing' \
29+
' ocean restart links'}
2630
}
2731

2832
NEMO_ENVIRONMENT_VARS_INITIAL = {
2933
'OCEAN_EXEC': {'desc': ('Ocean executable (OCEAN_EXEC=<full path to'
3034
' exec>)')},
31-
'NEMO_NPROC': {'desc': 'Number of NEMO processors'},
3235
'NEMO_IPROC': {'desc': 'Number of NEMO processors in the i direction'},
3336
'NEMO_JPROC': {'desc': 'Number of NEMO processors in the j direction'},
3437
'NEMO_VERSION': {},
3538
'OCEAN_LINK': {'default_val': 'ocean.exe'},
36-
'OCN_RES': {'default_val': ''},
3739
'NEMO_NL': {'default_val': 'namelist_cfg'},
3840
'NEMO_START': {'default_val': ''},
3941
'NEMO_ICEBERGS_START': {'default_val': ''},

Coupled_Drivers/dr_env_lib/ocn_cont_def.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
#!/usr/bin/env python3
1+
#!/usr/bin/env python
22
'''
33
*****************************COPYRIGHT******************************
4-
(C) Crown copyright 2021-2025 Met Office. All rights reserved.
4+
(C) Crown copyright 2021 Met Office. All rights reserved.
55
66
Use, duplication or disclosure of this code is subject to the restrictions
77
as set forth in the licence. If no licence has been raised with this copy
@@ -18,17 +18,17 @@
1818
Definition of the environment variables required for the ocean
1919
controllers
2020
'''
21+
SI3_ENVIRONMENT_VARS_COMMON = {'SI3_NL': {'default_val': 'namelist_ice_cfg'}}
22+
SI3_ENVIRONMENT_VARS_INITIAL = {'SI3_START': {'default_val': ''}}
2123

22-
SI3_ENVIRONMENT_VARS_INITIAL = {
23-
'SI3_START': {'default_val': ''},
24-
'SI3_NL': {'default_val': 'namelist_ice_cfg'}}
24+
SI3_ENVIRONMENT_VARS_INITIAL = {**SI3_ENVIRONMENT_VARS_COMMON,
25+
**SI3_ENVIRONMENT_VARS_INITIAL}
26+
SI3_ENVIRONMENT_VARS_FINAL = SI3_ENVIRONMENT_VARS_COMMON
2527

2628
TOP_ENVIRONMENT_VARS_COMMON = {
2729
'TOP_NL': {'default_val': 'namelist_top_cfg'}}
2830
TOP_ENVIRONMENT_VARS_INITIAL = {
29-
'TOP_START': {'default_val': ''},
30-
'CONTINUE': {'default_val': 'false'},
31-
'CONTINUE_FROM_FAIL': {'default_val': 'false'}}
31+
'TOP_START': {'default_val': ''}}
3232

3333
TOP_ENVIRONMENT_VARS_INITIAL = {**TOP_ENVIRONMENT_VARS_COMMON,
3434
**TOP_ENVIRONMENT_VARS_INITIAL}

Coupled_Drivers/error.py

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
#!/usr/bin/env python3
1+
#!/usr/bin/env python
22
'''
33
*****************************COPYRIGHT******************************
4-
(C) Crown copyright 2021-2025 Met Office. All rights reserved.
4+
(C) Crown copyright 2021 Met Office. All rights reserved.
55
66
Use, duplication or disclosure of this code is subject to the restrictions
77
as set forth in the licence. If no licence has been raised with this copy
@@ -23,9 +23,6 @@
2323
# Python errors
2424
VERSION_ERROR = 1
2525

26-
# Import Error
27-
IMPORT_ERROR = 2
28-
2926
# File I/O errors
3027
IOERROR = 100
3128

@@ -53,6 +50,9 @@
5350
# Invalid argument to driver script
5451
INVALID_DRIVER_ARG_ERROR = 202
5552

53+
# Missing file contents
54+
MISSING_FILE_CONTENTS_ERROR = 203
55+
5656
# Missing file required by a controller
5757
MISSING_CONTROLLER_FILE_ERROR = 251
5858

@@ -139,6 +139,9 @@
139139
# Unable to create remapping file for mapping type
140140
MISSING_RMP_MAPPING = 816
141141

142+
# Size of 1D grid is unknown
143+
UNKNOWN_1D_GRID_SIZE = 817
144+
142145
# Ocean resolution for Snr<->Jnr coupling is not specified
143146
NO_OCN_RESOL = 818
144147

@@ -181,17 +184,11 @@
181184
# Not on ORCA grid
182185
NOT_ORCA_GRID = 833
183186

184-
# Not declared ocean resolution when creating namcouple on fly after NEMO3.6
185-
NOT_DECLARE_OCN_RES = 834
186-
187-
# Unknown ocean resolution
188-
UNKNOWN_OCN_RESOL = 835
189-
190187
# Missing namelist oasis_ocn_send_nml from OASIS_OCN_SEND
191-
MISSING_OASIS_OCN_SEND_NML = 836
188+
MISSING_OASIS_OCN_SEND_NML = 834
192189

193190
# Missing entry oasis_ocn_send from namelist oasis_ocn_send_nml
194-
MISSING_OASIS_OCN_SEND = 837
191+
MISSING_OASIS_OCN_SEND = 835
195192

196193
# Missing OASIS send file for UM
197194
MISSING_OASIS_ATM_SEND = 840
@@ -257,15 +254,3 @@
257254

258255
# Not found the coupling namelist in namelist_cfg
259256
MISSING_NAMSBC_CPL = 871
260-
261-
# Missing the JULES river resolution namelist
262-
MISSING_RIVER_RESOL_NML = 872
263-
264-
# Missing the JULES river resolution parameters
265-
MISSING_RIVER_RESOL = 873
266-
267-
# Missing OASIS send file for JULES river
268-
MISSING_OASIS_RIV_SEND = 874
269-
270-
# Missing namelist oasis_riv_send_nml from OASIS_RIV_SEND
271-
MISSING_OASIS_RIV_SEND_NML = 875

Coupled_Drivers/fcm_make/driver.cfg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ extract.ns = drivers
1414
extract.location{primary}[drivers] = fcm:moci.xm
1515
extract.location[drivers] = $driver_base${driver_rev}
1616
extract.path-excl[drivers] = /
17-
extract.path-incl[drivers] = Coupled_Drivers Utilities/NGMS_utils/ngms_namcouple_gen Utilities/NGMS_utils/ngms_suite_lib
17+
extract.path-incl[drivers] = Coupled_Drivers
1818

19-
$install_common=
19+
$install_common = cice_driver.py common.py write_namcouple.py default_couplings.py error.py inc_days.py jnr_driver.py link_drivers mct_driver.py nemo_driver.py OASIS_fields run_model save_um_state.py time2days.py um_driver.py update_namcouple.py update_nemo_nl.py xios_driver.py plot_cpmip_summary.py cpmip_controller.py mct_validate.py ocn_lib.py nemo_runtime_namcouple.py nemo_driver.py
2020

2121
build.target = $install_common

0 commit comments

Comments
 (0)