From f071994c1e0f1a47cb92baf9575dcf4ee2e1c31a Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Tue, 25 Feb 2025 19:42:32 +0000 Subject: [PATCH 01/44] change noaacloud NodeName --- ci/Jenkinsfile4AWS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index cac3f4cd119..c23ace3a968 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -5,7 +5,7 @@ def HOMEgfs = 'none' def CI_CASES = '' def GH = 'none' // Location of the custom workspaces for each machine in the CI system. They are persistent for each iteration of the PR. -def NodeName = [hera: 'Hera-EMC', orion: 'Orion-EMC', hercules: 'Hercules-EMC', gaea: 'Gaea', noaacloud: 'AWS'] +def NodeName = [hera: 'Hera-EMC', orion: 'Orion-EMC', hercules: 'Hercules-EMC', gaea: 'Gaea', noaacloud: 'awsepicglobalworkflow'] def custom_workspace = [hera: '/scratch1/NCEPDEV/global/CI', orion: '/work2/noaa/stmp/CI/ORION', hercules: '/work2/noaa/global/CI/HERCULES', gaea: '/gpfs/f5/epic/proj-shared/global/CI', noaacloud: /lustre/jenkins/global-workflow/CI] def repo_url = 'git@github.com:NOAA-EMC/global-workflow.git' def STATUS = 'Passed' @@ -79,7 +79,7 @@ pipeline { Machine = machine[0].toUpperCase() + machine.substring(1) echo "Getting Common Workspace for ${Machine}" ws("${custom_workspace[machine]}/${env.CHANGE_ID}") { - properties([parameters([[$class: 'NodeParameterDefinition', allowedSlaves: ['built-in', 'Hercules-EMC', 'Hera-EMC', 'Orion-EMC', 'Gaea', 'AWS'], defaultSlaves: ['built-in'], name: '', nodeEligibility: [$class: 'AllNodeEligibility'], triggerIfResult: 'allCases']])]) + properties([parameters([[$class: 'NodeParameterDefinition', allowedSlaves: ['built-in', 'Hercules-EMC', 'Hera-EMC', 'Orion-EMC', 'Gaea', 'awsepicglobalworkflow'], defaultSlaves: ['built-in'], name: '', nodeEligibility: [$class: 'AllNodeEligibility'], triggerIfResult: 'allCases']])]) GH = sh(script: "which gh || echo '~/bin/gh'", returnStdout: true).trim() CUSTOM_WORKSPACE = "${WORKSPACE}" HOMEgfs = "${CUSTOM_WORKSPACE}/global-workflow" From a4771df691c38e0275f446fe295d1d00fe205538 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Wed, 26 Feb 2025 18:36:43 +0000 Subject: [PATCH 02/44] add download fix subset data, also serve as a test PR to trigger CI testing on AWS --- ush/fetch-fix-data.py | 331 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100644 ush/fetch-fix-data.py diff --git a/ush/fetch-fix-data.py b/ush/fetch-fix-data.py new file mode 100644 index 00000000000..717fecdcf7b --- /dev/null +++ b/ush/fetch-fix-data.py @@ -0,0 +1,331 @@ +#!/usr/bin/env python +# cfetch-fix-data.py +# wei.huang@noaa.gov +# 2025-02-26 +# script to download a subset of FIX data to local machines. +import os +import time +import sys +#import requests +#import json +#import base64 +import getopt +import subprocess +from pathlib import Path + +#---------------------------------------------------------------------------------------------------------------- +class FetchFIXdata(): + def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], localdir=None, verbose=0): + self.aws_fix_bucket = 's3://noaa-nws-global-pds/fix' + self.aws_cp = 'aws --no-sign-request s3 cp' + self.aws_sync = 'aws --no-sign-request s3 sync' + + self.atmgridarray = atmgridarray + self.ocngridarray = ocngridarray + self.localdir = localdir + self.verbose = verbose + + #if (os.path.isdir(localdir)): + # print('Prepare to download FIX data for %s and %s to %s' %(atmgrid, ocngrid, localdir)) + #else: + # print('local dir: <%s> does not exist. Stop' %(localdir)) + # sys.exit(-1) + + self.verdict = {} + self.s3dict = {} + self.s3dict['raworog'] = 'raw/orog' + + if (self.localdir.find('fix') < 0): + self.targetdir = '%s/fix.subset' %(self.localdir) + else: + self.targetdir = self.localdir + +#---------------------------------------------------------------------------------------------------------------- + def update_s3dict(self): + self.update_s3dick_grid_independent() + self.add_grid_data() + + if (self.verbose): + self.printinfo() + +#---------------------------------------------------------------------------------------------------------------- + def update_s3dick_grid_independent(self): + for key in self.fix_ver_dict.keys(): + val = self.fix_ver_dict[key] + if (key == 'aer_ver'): + self.s3dict['aer'] = 'aer/%s' %(val) + elif (key == 'am_ver'): + self.s3dict['am'] = 'am/%s' %(val) + elif (key == 'chem_ver'): + self.s3dict['fimdata_chem'] = 'chem/%s/fimdata_chem' %(val) + self.s3dict['Emission_data'] = 'chem/%s/Emission_data' %(val) + elif (key == 'datm_ver'): + self.s3dict['cfsr'] = 'datm/%s/cfsr' %(val) + self.s3dict['gefs'] = 'datm/%s/gefs' %(val) + self.s3dict['gfs'] = 'datm/%s/gfs' %(val) + self.s3dict['mom6'] = 'datm/%s/mom6' %(val) + elif (key == 'glwu_ver'): + self.s3dict['glwu'] = 'glwu/%s' %(val) + elif (key == 'gsi_ver'): + self.s3dict['gsi'] = 'gsi/%s' %(val) + elif (key == 'lut_ver'): + self.s3dict['lut'] = 'lut/%s' %(val) + elif (key == 'mom6_ver'): + self.s3dict['mom6post'] = 'mom6/%s/post' %(val) + elif (key == 'reg2grb2_ver'): + self.s3dict['reg2grb2'] = 'reg2grb2/%s' %(val) + elif (key == 'sfc_climb_ver'): + self.s3dict['sfc_climo'] = 'sfc_climo/%s' %(val) + elif (key == 'verif_ver'): + self.s3dict['verif'] = 'verif/%s' %(val) + elif (key == 'wave_ver'): + self.s3dict['wave'] = 'wave/%s' %(val) + +#---------------------------------------------------------------------------------------------------------------- + def add_grid_data(self): + for key in self.fix_ver_dict.keys(): + val = self.fix_ver_dict[key] + if (key == 'orog_ver'): + self.add_atmgrid2s3dict('orog', key, val) + elif (key == 'ugwd_ver'): + self.add_atmgrid2s3dict('ugwd', key, val) + elif (key == 'mom6_ver'): + self.add_ocngrid2s3dict('mom6', key, val) + elif (key == 'cice_ver'): + self.add_ocngrid2s3dict('cice', key, val) + elif (key == 'cpl_ver'): + self.add_cpl2s3dict('cpl', key, val) + +#---------------------------------------------------------------------------------------------------------------- + def add_atmgrid2s3dict(self, varname, key, val): + for atmgrid in self.atmgridarray: + newkey = '%s_%s' %(key, atmgrid) + self.s3dict[newkey] = '%s/%s/%s' %(varname, val, atmgrid) + +#---------------------------------------------------------------------------------------------------------------- + def add_ocngrid2s3dict(self, varname, key, val): + for ocngrid in self.ocngridarray: + newkey = '%s_%s' %(key, atmgrid) + self.s3dict[newkey] = '%s/%s/%s' %(varname, val, ocngrid) + +#---------------------------------------------------------------------------------------------------------------- + def add_cpl2s3dict(self, varname, key, val): + for atmgrid in self.atmgridarray: + for ocngrid in self.ocngridarray: + newkey = '%s_a%so%s' %(key, atmgrid, ocngrid) + self.s3dict[newkey] = '%s/%s/a%so%s' %(varname, val, atmgrid, ocngrid) + +#---------------------------------------------------------------------------------------------------------------- + def printinfo(self): + print('Preparing to fetch') + print('ATM grid: ', self.atmgridarray) + print('ONC grid: ', self.ocngridarray) + print('From: %s' %(self.aws_fix_bucket)) + print('To: %s' %(self.targetdir)) + for key in self.s3dict.keys(): + val = self.s3dict[key] + print('%s: %s' %(key, val)) + +#---------------------------------------------------------------------------------------------------------------- + def fetchdata(self): + if (self.verbose): + print('Create local fix dir: ', self.targetdir) + + path = Path(self.targetdir) + path.mkdir(parents=True, exist_ok=True) + + self.fetch_ugwp_limb_tau() + + for key in self.s3dict.keys(): + self.fetch_dir(self.s3dict[key]) + +#---------------------------------------------------------------------------------------------------------------- + def fetch_dir(self, dir): + remotedir = '%s/%s' %(self.aws_fix_bucket, dir) + localdir = '%s/%s' %(self.targetdir, dir) + cmd = '%s %s %s'%(self.aws_sync, remotedir, localdir) + self.download_dir(cmd, localdir) + +#---------------------------------------------------------------------------------------------------------------- + def download_dir(self, cmd, localdir): + #returned_value = os.system(cmd) # returns the exit code in unix + #print('returned value:', returned_value) + + if (os.path.isdir(localdir)): + print('%s already exist. skip' %(localdir)) + else: + parentdir, dirname = os.path.split(localdir) + if (self.verbose): + print('Create local %s dir: ', parentdir) + path = Path(parentdir) + path.mkdir(parents=True, exist_ok=True) + if (self.verbose): + print(cmd) + print('Downloading ', localdir) + returned_value = subprocess.call(cmd, shell=True) # returns the exit code in unix + if (self.verbose): + print('returned value:', returned_value) + +#---------------------------------------------------------------------------------------------------------------- + def fetch_ugwp_limb_tau(self): + ugwp_limb_tau_remotepath = '%s/ugwd/%s/ugwp_limb_tau.nc' %(self.aws_fix_bucket, self.fix_ver_dict['ugwd_ver']) + ugwp_limb_tau_localdir = '%s/ugwd/%s' %(self.targetdir, self.fix_ver_dict['ugwd_ver']) + filename = '%s/ugwp_limb_tau.nc' %(ugwp_limb_tau_localdir) + path = Path(ugwp_limb_tau_localdir) + path.mkdir(parents=True, exist_ok=True) + cmd = '%s %s %s'%(self.aws_cp, ugwp_limb_tau_remotepath, filename) + self.download_file(cmd, filename) + +#---------------------------------------------------------------------------------------------------------------- + def download_file(self, cmd, filename): + #returned_value = os.system(cmd) # returns the exit code in unix + #print('returned value:', returned_value) + + if (os.path.isfile(filename)): + print('%s already exist. skip' %(filename)) + else: + if (self.verbose): + print(cmd) + print('Downloading ', filename) + returned_value = subprocess.call(cmd, shell=True) # returns the exit code in unix + if (self.verbose): + print('returned value:', returned_value) + +#---------------------------------------------------------------------------------------------------------------- + def set_fix_ver_from_gwhome(self, gwhome, verdict): + fix_ver_file = '%s/versions/fix.ver' + self.fix_ver_dict = verdict + if (os.path.isfile(fix_ver_file)): + with open(fix_ver_file, "r") as file: + for line in file.readlines(): + if (line.find('export ') >= 0): + headstr, _, value = line.strip().partition('=') + exphead, _, key = headstr.partition(' ') + self.fix_ver_dict[key] = value + else: + print('fix_ver_file: %s does not exist.' %(fix_ver_file)) + +#---------------------------------------------------------------------------------------------------------------- + def set_default_fix_ver(self, verdict): + self.fix_ver_dict = verdict + +#---------------------------------------------------------------------------------------------------------------- +def print_usage(verdict): + print('Usage: python fetch-fix-data.py \\') + print(' --atmgrid=AtmospericGrid (for multiple grids, separate with ",") \\') + print(' --ocngrid=OceanGrid (for multiple grids, separate with ",") \\') + print(' --localdir=Your-local-fix-dir \\') + print(' [options]') + print('options are:') + print('\t--gwhome=xxxx (Global-Workflow directory)') + + for key in verdict.keys(): + print('\t--%s=yyyymmdd default: %s' %(key, verdict[key])) + +#---------------------------------------------------------------------------------------------------------------- +if __name__ == '__main__': + atmgridlist = ['C48', 'C96', 'C192', 'C384', 'C768', 'C1152'] + ocngridlist = ['500', '100', '050', '025'] + + verbose = 0 + atmgrid = 'C48' + ocngrid = '500' + localdir = '/contrib/global-workflow-shared-data' + + #default fix-version + verdict = {} + verdict['aer_ver'] = '20220805' + verdict['am_ver'] = '20220805' + verdict['chem_ver'] = '20220805' + verdict['cice_ver'] = '20240416' + verdict['cpl_ver'] = '20230526' + verdict['datm_ver'] = '20220805' + verdict['glwu_ver'] = '20220805' + verdict['gsi_ver'] = '20240208' + verdict['lut_ver'] = '20220805' + verdict['mom6_ver'] = '20240416' + verdict['orog_ver'] = '20231027' + verdict['reg2grb2_ver'] = '20220805' + verdict['sfc_climo_ver'] = '20220805' + verdict['ugwd_ver'] = '20240624' + verdict['verif_ver'] = '20220805' + verdict['wave_ver'] = '20240105' + + gwhome=None + + opts, args = getopt.getopt(sys.argv[1:], '', ['help', 'atmgrid=', 'ocngrid=', + 'verbose=', 'localdir=', + 'gwhome=', + 'aer_ver=', + 'am_ver=', + 'chem_ver=', + 'cice_ver=', + 'cpl_ver=', + 'datm_ver=', + 'glwu_ver=', + 'gsi_ver=', + 'lut_ver=', + 'mom6_ver=', + 'orog_ver=', + 'reg2grb2_ver=', + 'sfc_climo_ver=', + 'ugwd_ver=', + 'verif_ver=', + 'wave_ver=']) + for o, a in opts: + print('o: %s, a: %s' %(o, a)) + if o in ['--help']: + print_usage(verdict) + sys.exit(0) + elif o in ['--verbose']: + verbose = int(a) + elif o in ['--atmgrid']: + atmgrid = a + elif o in ['--ocngrid']: + ocngrid = a + elif o in ['--localdir']: + localdir = a + elif o in ['--gwhome']: + gwhome = a + else: + _, vername = o.split('--') + print('vername: <%s>' %(vername)) + verdict[vername] = a + + if (atmgrid.find(',') > 0): + atmgridarray = atmgrid.split(',') + else: + atmgridarray = [atmgrid] + + for grid in atmgridarray: + if (grid not in atmgridlist): + print('atmgrid: ', grid) + print('is not in supported grids: ', atmgridlist) + print_usage(verdict) + sys.exit(-1) + + if (ocngrid.find(',') > 0): + ocngridarray = ocngrid.split(',') + else: + ocngridarray = [ocngrid] + + for grid in ocngridarray: + if (grid not in ocngridlist): + print('ocngrid: ', grid) + print('is not in supported grids: ', ocngridlist) + print_usage(verdict) + sys.exit(-1) + +#------------------------------------------------------------------ + ffd = FetchFIXdata(atmgridarray=atmgridarray, + ocngridarray=ocngridarray, + localdir=localdir, verbose=verbose) + + if (gwhome is None): + ffd.set_default_fix_ver(verdict) + else: + ffd.set_fix_ver_from_gwhome(gwhome, verdict) + + ffd.update_s3dict() + + ffd.fetchdata() From 4f1e67956a9718dee7cc5e0c784df55ca6f15d61 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Wed, 26 Feb 2025 19:26:17 +0000 Subject: [PATCH 03/44] fix pynorm error --- ush/fetch-fix-data.py | 126 +++++++++++++++++++++++------------------- 1 file changed, 70 insertions(+), 56 deletions(-) diff --git a/ush/fetch-fix-data.py b/ush/fetch-fix-data.py index 717fecdcf7b..ce4fa1bdec4 100644 --- a/ush/fetch-fix-data.py +++ b/ush/fetch-fix-data.py @@ -6,9 +6,6 @@ import os import time import sys -#import requests -#import json -#import base64 import getopt import subprocess from pathlib import Path @@ -16,6 +13,7 @@ #---------------------------------------------------------------------------------------------------------------- class FetchFIXdata(): def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], localdir=None, verbose=0): + self.aws_fix_bucket = 's3://noaa-nws-global-pds/fix' self.aws_cp = 'aws --no-sign-request s3 cp' self.aws_sync = 'aws --no-sign-request s3 sync' @@ -25,11 +23,11 @@ def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], localdir=None, ve self.localdir = localdir self.verbose = verbose - #if (os.path.isdir(localdir)): - # print('Prepare to download FIX data for %s and %s to %s' %(atmgrid, ocngrid, localdir)) - #else: - # print('local dir: <%s> does not exist. Stop' %(localdir)) - # sys.exit(-1) + #if (os.path.isdir(localdir)): + # print('Prepare to download FIX data for %s and %s to %s' %(atmgrid, ocngrid, localdir)) + #else: + # print('local dir: <%s> does not exist. Stop' %(localdir)) + # sys.exit(-1) self.verdict = {} self.s3dict = {} @@ -40,49 +38,52 @@ def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], localdir=None, ve else: self.targetdir = self.localdir -#---------------------------------------------------------------------------------------------------------------- + #---------------------------------------------------------------------------------------------------------------- def update_s3dict(self): + self.update_s3dick_grid_independent() self.add_grid_data() if (self.verbose): self.printinfo() -#---------------------------------------------------------------------------------------------------------------- + #---------------------------------------------------------------------------------------------------------------- def update_s3dick_grid_independent(self): + for key in self.fix_ver_dict.keys(): val = self.fix_ver_dict[key] if (key == 'aer_ver'): - self.s3dict['aer'] = 'aer/%s' %(val) + self.s3dict['aer'] = 'aer/%s' %( val ) elif (key == 'am_ver'): - self.s3dict['am'] = 'am/%s' %(val) + self.s3dict['am'] = 'am/%s' %( val ) elif (key == 'chem_ver'): - self.s3dict['fimdata_chem'] = 'chem/%s/fimdata_chem' %(val) - self.s3dict['Emission_data'] = 'chem/%s/Emission_data' %(val) + self.s3dict['fimdata_chem'] = 'chem/%s/fimdata_chem' %( val ) + self.s3dict['Emission_data'] = 'chem/%s/Emission_data' %( val ) elif (key == 'datm_ver'): - self.s3dict['cfsr'] = 'datm/%s/cfsr' %(val) - self.s3dict['gefs'] = 'datm/%s/gefs' %(val) - self.s3dict['gfs'] = 'datm/%s/gfs' %(val) - self.s3dict['mom6'] = 'datm/%s/mom6' %(val) + self.s3dict['cfsr'] = 'datm/%s/cfsr' %( val ) + self.s3dict['gefs'] = 'datm/%s/gefs' %( val ) + self.s3dict['gfs'] = 'datm/%s/gfs' %( val ) + self.s3dict['mom6'] = 'datm/%s/mom6' %( val ) elif (key == 'glwu_ver'): - self.s3dict['glwu'] = 'glwu/%s' %(val) + self.s3dict['glwu'] = 'glwu/%s' %( val ) elif (key == 'gsi_ver'): - self.s3dict['gsi'] = 'gsi/%s' %(val) + self.s3dict['gsi'] = 'gsi/%s' %( val ) elif (key == 'lut_ver'): - self.s3dict['lut'] = 'lut/%s' %(val) + self.s3dict['lut'] = 'lut/%s' %( val ) elif (key == 'mom6_ver'): - self.s3dict['mom6post'] = 'mom6/%s/post' %(val) + self.s3dict['mom6post'] = 'mom6/%s/post' %( val ) elif (key == 'reg2grb2_ver'): - self.s3dict['reg2grb2'] = 'reg2grb2/%s' %(val) + self.s3dict['reg2grb2'] = 'reg2grb2/%s' %( val ) elif (key == 'sfc_climb_ver'): - self.s3dict['sfc_climo'] = 'sfc_climo/%s' %(val) + self.s3dict['sfc_climo'] = 'sfc_climo/%s' %( val ) elif (key == 'verif_ver'): - self.s3dict['verif'] = 'verif/%s' %(val) + self.s3dict['verif'] = 'verif/%s' %( val ) elif (key == 'wave_ver'): - self.s3dict['wave'] = 'wave/%s' %(val) + self.s3dict['wave'] = 'wave/%s' %( val ) -#---------------------------------------------------------------------------------------------------------------- + #---------------------------------------------------------------------------------------------------------------- def add_grid_data(self): + for key in self.fix_ver_dict.keys(): val = self.fix_ver_dict[key] if (key == 'orog_ver'): @@ -96,38 +97,43 @@ def add_grid_data(self): elif (key == 'cpl_ver'): self.add_cpl2s3dict('cpl', key, val) -#---------------------------------------------------------------------------------------------------------------- + #---------------------------------------------------------------------------------------------------------------- def add_atmgrid2s3dict(self, varname, key, val): + for atmgrid in self.atmgridarray: - newkey = '%s_%s' %(key, atmgrid) - self.s3dict[newkey] = '%s/%s/%s' %(varname, val, atmgrid) + newkey = '%s_%s' %( key, atmgrid ) + self.s3dict[newkey] = '%s/%s/%s' %( varname, val, atmgrid ) -#---------------------------------------------------------------------------------------------------------------- + #---------------------------------------------------------------------------------------------------------------- def add_ocngrid2s3dict(self, varname, key, val): + for ocngrid in self.ocngridarray: - newkey = '%s_%s' %(key, atmgrid) - self.s3dict[newkey] = '%s/%s/%s' %(varname, val, ocngrid) + newkey = '%s_%s' %( key, atmgrid ) + self.s3dict[newkey] = '%s/%s/%s' %( varname, val, ocngrid ) -#---------------------------------------------------------------------------------------------------------------- + #---------------------------------------------------------------------------------------------------------------- def add_cpl2s3dict(self, varname, key, val): + for atmgrid in self.atmgridarray: for ocngrid in self.ocngridarray: - newkey = '%s_a%so%s' %(key, atmgrid, ocngrid) - self.s3dict[newkey] = '%s/%s/a%so%s' %(varname, val, atmgrid, ocngrid) + newkey = '%s_a%so%s' %( key, atmgrid, ocngrid ) + self.s3dict[newkey] = '%s/%s/a%so%s' %( varname, val, atmgrid, ocngrid ) -#---------------------------------------------------------------------------------------------------------------- + #---------------------------------------------------------------------------------------------------------------- def printinfo(self): + print('Preparing to fetch') print('ATM grid: ', self.atmgridarray) print('ONC grid: ', self.ocngridarray) - print('From: %s' %(self.aws_fix_bucket)) - print('To: %s' %(self.targetdir)) + print('From: %s' %( self.aws_fix_bucket )) + print('To: %s' %( self.targetdir )) for key in self.s3dict.keys(): val = self.s3dict[key] - print('%s: %s' %(key, val)) + print('%s: %s' %( key, val )) -#---------------------------------------------------------------------------------------------------------------- + #---------------------------------------------------------------------------------------------------------------- def fetchdata(self): + if (self.verbose): print('Create local fix dir: ', self.targetdir) @@ -139,17 +145,19 @@ def fetchdata(self): for key in self.s3dict.keys(): self.fetch_dir(self.s3dict[key]) -#---------------------------------------------------------------------------------------------------------------- + #---------------------------------------------------------------------------------------------------------------- def fetch_dir(self, dir): + remotedir = '%s/%s' %(self.aws_fix_bucket, dir) - localdir = '%s/%s' %(self.targetdir, dir) + localdir = '%s/%s' %( self.targetdir, dir ) cmd = '%s %s %s'%(self.aws_sync, remotedir, localdir) self.download_dir(cmd, localdir) -#---------------------------------------------------------------------------------------------------------------- + #---------------------------------------------------------------------------------------------------------------- def download_dir(self, cmd, localdir): - #returned_value = os.system(cmd) # returns the exit code in unix - #print('returned value:', returned_value) + + #returned_value = os.system(cmd) # returns the exit code in unix + #print('returned value:', returned_value) if (os.path.isdir(localdir)): print('%s already exist. skip' %(localdir)) @@ -166,8 +174,9 @@ def download_dir(self, cmd, localdir): if (self.verbose): print('returned value:', returned_value) -#---------------------------------------------------------------------------------------------------------------- + #---------------------------------------------------------------------------------------------------------------- def fetch_ugwp_limb_tau(self): + ugwp_limb_tau_remotepath = '%s/ugwd/%s/ugwp_limb_tau.nc' %(self.aws_fix_bucket, self.fix_ver_dict['ugwd_ver']) ugwp_limb_tau_localdir = '%s/ugwd/%s' %(self.targetdir, self.fix_ver_dict['ugwd_ver']) filename = '%s/ugwp_limb_tau.nc' %(ugwp_limb_tau_localdir) @@ -176,13 +185,14 @@ def fetch_ugwp_limb_tau(self): cmd = '%s %s %s'%(self.aws_cp, ugwp_limb_tau_remotepath, filename) self.download_file(cmd, filename) -#---------------------------------------------------------------------------------------------------------------- + #---------------------------------------------------------------------------------------------------------------- def download_file(self, cmd, filename): + #returned_value = os.system(cmd) # returns the exit code in unix #print('returned value:', returned_value) if (os.path.isfile(filename)): - print('%s already exist. skip' %(filename)) + print('%s already exist. skip' %( filename )) else: if (self.verbose): print(cmd) @@ -191,8 +201,9 @@ def download_file(self, cmd, filename): if (self.verbose): print('returned value:', returned_value) -#---------------------------------------------------------------------------------------------------------------- + #---------------------------------------------------------------------------------------------------------------- def set_fix_ver_from_gwhome(self, gwhome, verdict): + fix_ver_file = '%s/versions/fix.ver' self.fix_ver_dict = verdict if (os.path.isfile(fix_ver_file)): @@ -205,12 +216,14 @@ def set_fix_ver_from_gwhome(self, gwhome, verdict): else: print('fix_ver_file: %s does not exist.' %(fix_ver_file)) -#---------------------------------------------------------------------------------------------------------------- + #---------------------------------------------------------------------------------------------------------------- def set_default_fix_ver(self, verdict): + self.fix_ver_dict = verdict #---------------------------------------------------------------------------------------------------------------- def print_usage(verdict): + print('Usage: python fetch-fix-data.py \\') print(' --atmgrid=AtmospericGrid (for multiple grids, separate with ",") \\') print(' --ocngrid=OceanGrid (for multiple grids, separate with ",") \\') @@ -220,10 +233,11 @@ def print_usage(verdict): print('\t--gwhome=xxxx (Global-Workflow directory)') for key in verdict.keys(): - print('\t--%s=yyyymmdd default: %s' %(key, verdict[key])) + print( '\t--%s=yyyymmdd default: %s' %( key, verdict[key] ) ) #---------------------------------------------------------------------------------------------------------------- if __name__ == '__main__': + atmgridlist = ['C48', 'C96', 'C192', 'C384', 'C768', 'C1152'] ocngridlist = ['500', '100', '050', '025'] @@ -232,7 +246,7 @@ def print_usage(verdict): ocngrid = '500' localdir = '/contrib/global-workflow-shared-data' - #default fix-version + #default fix-version verdict = {} verdict['aer_ver'] = '20220805' verdict['am_ver'] = '20220805' @@ -273,7 +287,7 @@ def print_usage(verdict): 'verif_ver=', 'wave_ver=']) for o, a in opts: - print('o: %s, a: %s' %(o, a)) + #print( 'o: %s, a: %s' %(o, a) ) if o in ['--help']: print_usage(verdict) sys.exit(0) @@ -289,7 +303,7 @@ def print_usage(verdict): gwhome = a else: _, vername = o.split('--') - print('vername: <%s>' %(vername)) + print( 'vername: <%s>' %(vername) ) verdict[vername] = a if (atmgrid.find(',') > 0): @@ -316,7 +330,7 @@ def print_usage(verdict): print_usage(verdict) sys.exit(-1) -#------------------------------------------------------------------ + #------------------------------------------------------------------ ffd = FetchFIXdata(atmgridarray=atmgridarray, ocngridarray=ocngridarray, localdir=localdir, verbose=verbose) From 2241227b7319fc5dfdc6b866fbef281dc0144a65 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Wed, 26 Feb 2025 20:10:17 +0000 Subject: [PATCH 04/44] fix pynorm error 2 --- ush/fetch-fix-data.py | 107 +++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 53 deletions(-) diff --git a/ush/fetch-fix-data.py b/ush/fetch-fix-data.py index ce4fa1bdec4..2a39f0d60d0 100644 --- a/ush/fetch-fix-data.py +++ b/ush/fetch-fix-data.py @@ -10,8 +10,9 @@ import subprocess from pathlib import Path -#---------------------------------------------------------------------------------------------------------------- +# ---------------------------------------------------------------------------------------------------------------- class FetchFIXdata(): + def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], localdir=None, verbose=0): self.aws_fix_bucket = 's3://noaa-nws-global-pds/fix' @@ -38,7 +39,7 @@ def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], localdir=None, ve else: self.targetdir = self.localdir - #---------------------------------------------------------------------------------------------------------------- + # ---------------------------------------------------------------------------------------------------------------- def update_s3dict(self): self.update_s3dick_grid_independent() @@ -47,41 +48,41 @@ def update_s3dict(self): if (self.verbose): self.printinfo() - #---------------------------------------------------------------------------------------------------------------- + # ---------------------------------------------------------------------------------------------------------------- def update_s3dick_grid_independent(self): for key in self.fix_ver_dict.keys(): val = self.fix_ver_dict[key] - if (key == 'aer_ver'): - self.s3dict['aer'] = 'aer/%s' %( val ) - elif (key == 'am_ver'): - self.s3dict['am'] = 'am/%s' %( val ) - elif (key == 'chem_ver'): - self.s3dict['fimdata_chem'] = 'chem/%s/fimdata_chem' %( val ) - self.s3dict['Emission_data'] = 'chem/%s/Emission_data' %( val ) - elif (key == 'datm_ver'): - self.s3dict['cfsr'] = 'datm/%s/cfsr' %( val ) - self.s3dict['gefs'] = 'datm/%s/gefs' %( val ) - self.s3dict['gfs'] = 'datm/%s/gfs' %( val ) - self.s3dict['mom6'] = 'datm/%s/mom6' %( val ) - elif (key == 'glwu_ver'): - self.s3dict['glwu'] = 'glwu/%s' %( val ) - elif (key == 'gsi_ver'): - self.s3dict['gsi'] = 'gsi/%s' %( val ) - elif (key == 'lut_ver'): - self.s3dict['lut'] = 'lut/%s' %( val ) - elif (key == 'mom6_ver'): - self.s3dict['mom6post'] = 'mom6/%s/post' %( val ) - elif (key == 'reg2grb2_ver'): - self.s3dict['reg2grb2'] = 'reg2grb2/%s' %( val ) - elif (key == 'sfc_climb_ver'): - self.s3dict['sfc_climo'] = 'sfc_climo/%s' %( val ) - elif (key == 'verif_ver'): - self.s3dict['verif'] = 'verif/%s' %( val ) - elif (key == 'wave_ver'): - self.s3dict['wave'] = 'wave/%s' %( val ) - - #---------------------------------------------------------------------------------------------------------------- + if ( key == 'aer_ver' ): + self.s3dict['aer'] = 'aer/%s' %(val) + elif ( key == 'am_ver' ): + self.s3dict['am'] = 'am/%s' %(val) + elif ( key == 'chem_ver' ): + self.s3dict['fimdata_chem'] = 'chem/%s/fimdata_chem' %(val) + self.s3dict['Emission_data'] = 'chem/%s/Emission_data' %(val) + elif ( key == 'datm_ver' ): + self.s3dict['cfsr'] = 'datm/%s/cfsr' %(val) + self.s3dict['gefs'] = 'datm/%s/gefs' %(val) + self.s3dict['gfs'] = 'datm/%s/gfs' %(val) + self.s3dict['mom6'] = 'datm/%s/mom6' %(val) + elif ( key == 'glwu_ver' ): + self.s3dict['glwu'] = 'glwu/%s' %(val) + elif ( key == 'gsi_ver' ): + self.s3dict['gsi'] = 'gsi/%s' %(val) + elif ( key == 'lut_ver' ): + self.s3dict['lut'] = 'lut/%s' %(val) + elif ( key == 'mom6_ver' ): + self.s3dict['mom6post'] = 'mom6/%s/post' %(val) + elif ( key == 'reg2grb2_ver' ): + self.s3dict['reg2grb2'] = 'reg2grb2/%s' %(val) + elif ( key == 'sfc_climb_ver' ): + self.s3dict['sfc_climo'] = 'sfc_climo/%s' %(val) + elif ( key == 'verif_ver' ): + self.s3dict['verif'] = 'verif/%s' %(val) + elif ( key == 'wave_ver' ): + self.s3dict['wave'] = 'wave/%s' %(val) + + # ---------------------------------------------------------------------------------------------------------------- def add_grid_data(self): for key in self.fix_ver_dict.keys(): @@ -97,29 +98,29 @@ def add_grid_data(self): elif (key == 'cpl_ver'): self.add_cpl2s3dict('cpl', key, val) - #---------------------------------------------------------------------------------------------------------------- + # ---------------------------------------------------------------------------------------------------------------- def add_atmgrid2s3dict(self, varname, key, val): for atmgrid in self.atmgridarray: newkey = '%s_%s' %( key, atmgrid ) - self.s3dict[newkey] = '%s/%s/%s' %( varname, val, atmgrid ) + self.s3dict[newkey] = '%s/%s/%s' %(varname, val, atmgrid) - #---------------------------------------------------------------------------------------------------------------- + # ---------------------------------------------------------------------------------------------------------------- def add_ocngrid2s3dict(self, varname, key, val): for ocngrid in self.ocngridarray: - newkey = '%s_%s' %( key, atmgrid ) - self.s3dict[newkey] = '%s/%s/%s' %( varname, val, ocngrid ) + newkey = '%s_%s' %(key, atmgrid) + self.s3dict[newkey] = '%s/%s/%s' %(varname, val, ocngrid) - #---------------------------------------------------------------------------------------------------------------- + # ---------------------------------------------------------------------------------------------------------------- def add_cpl2s3dict(self, varname, key, val): for atmgrid in self.atmgridarray: for ocngrid in self.ocngridarray: newkey = '%s_a%so%s' %( key, atmgrid, ocngrid ) - self.s3dict[newkey] = '%s/%s/a%so%s' %( varname, val, atmgrid, ocngrid ) + self.s3dict[newkey] = '%s/%s/a%so%s' %(varname, val, atmgrid, ocngrid) - #---------------------------------------------------------------------------------------------------------------- + # ---------------------------------------------------------------------------------------------------------------- def printinfo(self): print('Preparing to fetch') @@ -131,7 +132,7 @@ def printinfo(self): val = self.s3dict[key] print('%s: %s' %( key, val )) - #---------------------------------------------------------------------------------------------------------------- + # ---------------------------------------------------------------------------------------------------------------- def fetchdata(self): if (self.verbose): @@ -145,15 +146,15 @@ def fetchdata(self): for key in self.s3dict.keys(): self.fetch_dir(self.s3dict[key]) - #---------------------------------------------------------------------------------------------------------------- + # ---------------------------------------------------------------------------------------------------------------- def fetch_dir(self, dir): remotedir = '%s/%s' %(self.aws_fix_bucket, dir) localdir = '%s/%s' %( self.targetdir, dir ) - cmd = '%s %s %s'%(self.aws_sync, remotedir, localdir) + cmd = '%s %s %s' %(self.aws_sync, remotedir, localdir) self.download_dir(cmd, localdir) - #---------------------------------------------------------------------------------------------------------------- + # ---------------------------------------------------------------------------------------------------------------- def download_dir(self, cmd, localdir): #returned_value = os.system(cmd) # returns the exit code in unix @@ -164,7 +165,7 @@ def download_dir(self, cmd, localdir): else: parentdir, dirname = os.path.split(localdir) if (self.verbose): - print('Create local %s dir: ', parentdir) + print('Create local %s dir: ' %(parentdir)) path = Path(parentdir) path.mkdir(parents=True, exist_ok=True) if (self.verbose): @@ -174,7 +175,7 @@ def download_dir(self, cmd, localdir): if (self.verbose): print('returned value:', returned_value) - #---------------------------------------------------------------------------------------------------------------- + # ---------------------------------------------------------------------------------------------------------------- def fetch_ugwp_limb_tau(self): ugwp_limb_tau_remotepath = '%s/ugwd/%s/ugwp_limb_tau.nc' %(self.aws_fix_bucket, self.fix_ver_dict['ugwd_ver']) @@ -185,7 +186,7 @@ def fetch_ugwp_limb_tau(self): cmd = '%s %s %s'%(self.aws_cp, ugwp_limb_tau_remotepath, filename) self.download_file(cmd, filename) - #---------------------------------------------------------------------------------------------------------------- + # ---------------------------------------------------------------------------------------------------------------- def download_file(self, cmd, filename): #returned_value = os.system(cmd) # returns the exit code in unix @@ -201,7 +202,7 @@ def download_file(self, cmd, filename): if (self.verbose): print('returned value:', returned_value) - #---------------------------------------------------------------------------------------------------------------- + # ---------------------------------------------------------------------------------------------------------------- def set_fix_ver_from_gwhome(self, gwhome, verdict): fix_ver_file = '%s/versions/fix.ver' @@ -216,12 +217,12 @@ def set_fix_ver_from_gwhome(self, gwhome, verdict): else: print('fix_ver_file: %s does not exist.' %(fix_ver_file)) - #---------------------------------------------------------------------------------------------------------------- + # ---------------------------------------------------------------------------------------------------------------- def set_default_fix_ver(self, verdict): self.fix_ver_dict = verdict -#---------------------------------------------------------------------------------------------------------------- +# ---------------------------------------------------------------------------------------------------------------- def print_usage(verdict): print('Usage: python fetch-fix-data.py \\') @@ -235,7 +236,7 @@ def print_usage(verdict): for key in verdict.keys(): print( '\t--%s=yyyymmdd default: %s' %( key, verdict[key] ) ) -#---------------------------------------------------------------------------------------------------------------- +# ---------------------------------------------------------------------------------------------------------------- if __name__ == '__main__': atmgridlist = ['C48', 'C96', 'C192', 'C384', 'C768', 'C1152'] @@ -330,7 +331,7 @@ def print_usage(verdict): print_usage(verdict) sys.exit(-1) - #------------------------------------------------------------------ + # ------------------------------------------------------------------ ffd = FetchFIXdata(atmgridarray=atmgridarray, ocngridarray=ocngridarray, localdir=localdir, verbose=verbose) From 9679617e8c7f9bc2978e7b66036fefe9e44f282b Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Wed, 26 Feb 2025 21:06:38 +0000 Subject: [PATCH 05/44] fix pynorm error3 --- ush/fetch-fix-data.py | 64 +++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/ush/fetch-fix-data.py b/ush/fetch-fix-data.py index 2a39f0d60d0..558f12bee9b 100644 --- a/ush/fetch-fix-data.py +++ b/ush/fetch-fix-data.py @@ -24,10 +24,10 @@ def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], localdir=None, ve self.localdir = localdir self.verbose = verbose - #if (os.path.isdir(localdir)): + # if (os.path.isdir(localdir)): # print('Prepare to download FIX data for %s and %s to %s' %(atmgrid, ocngrid, localdir)) - #else: - # print('local dir: <%s> does not exist. Stop' %(localdir)) + # else: + # print(f'local dir: <{localdir}> does not exist. Stop') # sys.exit(-1) self.verdict = {} @@ -35,7 +35,7 @@ def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], localdir=None, ve self.s3dict['raworog'] = 'raw/orog' if (self.localdir.find('fix') < 0): - self.targetdir = '%s/fix.subset' %(self.localdir) + self.targetdir = f'{self.localdir}/fix.subset' else: self.targetdir = self.localdir @@ -53,34 +53,34 @@ def update_s3dick_grid_independent(self): for key in self.fix_ver_dict.keys(): val = self.fix_ver_dict[key] - if ( key == 'aer_ver' ): - self.s3dict['aer'] = 'aer/%s' %(val) - elif ( key == 'am_ver' ): - self.s3dict['am'] = 'am/%s' %(val) - elif ( key == 'chem_ver' ): - self.s3dict['fimdata_chem'] = 'chem/%s/fimdata_chem' %(val) - self.s3dict['Emission_data'] = 'chem/%s/Emission_data' %(val) - elif ( key == 'datm_ver' ): - self.s3dict['cfsr'] = 'datm/%s/cfsr' %(val) - self.s3dict['gefs'] = 'datm/%s/gefs' %(val) - self.s3dict['gfs'] = 'datm/%s/gfs' %(val) - self.s3dict['mom6'] = 'datm/%s/mom6' %(val) - elif ( key == 'glwu_ver' ): - self.s3dict['glwu'] = 'glwu/%s' %(val) - elif ( key == 'gsi_ver' ): - self.s3dict['gsi'] = 'gsi/%s' %(val) - elif ( key == 'lut_ver' ): - self.s3dict['lut'] = 'lut/%s' %(val) - elif ( key == 'mom6_ver' ): - self.s3dict['mom6post'] = 'mom6/%s/post' %(val) - elif ( key == 'reg2grb2_ver' ): - self.s3dict['reg2grb2'] = 'reg2grb2/%s' %(val) - elif ( key == 'sfc_climb_ver' ): - self.s3dict['sfc_climo'] = 'sfc_climo/%s' %(val) - elif ( key == 'verif_ver' ): - self.s3dict['verif'] = 'verif/%s' %(val) - elif ( key == 'wave_ver' ): - self.s3dict['wave'] = 'wave/%s' %(val) + if (key == 'aer_ver'): + self.s3dict['aer'] = f'aer/{val}' + elif ( key == 'am_ver'): + self.s3dict['am'] = f'am/{val}' + elif (key == 'chem_ver'): + self.s3dict['fimdata_chem'] = f'chem/{val}/fimdata_chem' + self.s3dict['Emission_data'] = f'chem/{val}/Emission_data' + elif (key == 'datm_ver'): + self.s3dict['cfsr'] = f'datm/{val}/cfsr' + self.s3dict['gefs'] = f'datm/{val}/gefs' + self.s3dict['gfs'] = f'datm/{val}/gfs' + self.s3dict['mom6'] = f'datm/{val}/mom6' + elif (key == 'glwu_ver'): + self.s3dict['glwu'] = f'glwu/{val}' + elif (key == 'gsi_ver'): + self.s3dict['gsi'] = f'gsi/{val}' + elif (key == 'lut_ver'): + self.s3dict['lut'] = f'lut/{val}' + elif (key == 'mom6_ver'): + self.s3dict['mom6post'] = f'mom6/{val}/post' + elif (key == 'reg2grb2_ver'): + self.s3dict['reg2grb2'] = f'reg2grb2/{val}' + elif (key == 'sfc_climb_ver' ): + self.s3dict['sfc_climo'] = f'sfc_climo/{val}' + elif (key == 'verif_ver'): + self.s3dict['verif'] = f'verif/{val}' + elif (key == 'wave_ver'): + self.s3dict['wave'] = f'wave/{val}' # ---------------------------------------------------------------------------------------------------------------- def add_grid_data(self): From fe887515dc8b8b3bed8312d189fb3ceddbe9ed85 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Wed, 26 Feb 2025 21:31:00 +0000 Subject: [PATCH 06/44] fix pynorm error 4 --- ush/fetch-fix-data.py | 74 ++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/ush/fetch-fix-data.py b/ush/fetch-fix-data.py index 558f12bee9b..fe7120285e1 100644 --- a/ush/fetch-fix-data.py +++ b/ush/fetch-fix-data.py @@ -102,41 +102,41 @@ def add_grid_data(self): def add_atmgrid2s3dict(self, varname, key, val): for atmgrid in self.atmgridarray: - newkey = '%s_%s' %( key, atmgrid ) - self.s3dict[newkey] = '%s/%s/%s' %(varname, val, atmgrid) + newkey = f'{key}_{atmgrid}' + self.s3dict[newkey] = f'{varname}/{val}/{atmgrid}' # ---------------------------------------------------------------------------------------------------------------- def add_ocngrid2s3dict(self, varname, key, val): for ocngrid in self.ocngridarray: - newkey = '%s_%s' %(key, atmgrid) - self.s3dict[newkey] = '%s/%s/%s' %(varname, val, ocngrid) + newkey = f'{key}_{atmgrid}' + self.s3dict[newkey] = f'{varname}/{val}/{ocngrid}' # ---------------------------------------------------------------------------------------------------------------- def add_cpl2s3dict(self, varname, key, val): for atmgrid in self.atmgridarray: for ocngrid in self.ocngridarray: - newkey = '%s_a%so%s' %( key, atmgrid, ocngrid ) - self.s3dict[newkey] = '%s/%s/a%so%s' %(varname, val, atmgrid, ocngrid) + newkey = f'{key}_a{atmgrid}o{ocngrid}' + self.s3dict[newkey] = f'{varname}/{val}/a{atmgrid}o{ocngrid}' # ---------------------------------------------------------------------------------------------------------------- def printinfo(self): - print('Preparing to fetch') - print('ATM grid: ', self.atmgridarray) - print('ONC grid: ', self.ocngridarray) - print('From: %s' %( self.aws_fix_bucket )) - print('To: %s' %( self.targetdir )) + print(f'Preparing to fetch') + print(f'ATM grid: {self.atmgridarray}') + print(f'ONC grid: {self.ocngridarray}') + print(f'From: {self.aws_fix_bucket}') + print(f'To: {self.targetdir}') for key in self.s3dict.keys(): val = self.s3dict[key] - print('%s: %s' %( key, val )) + print(f'{key}: {val}') # ---------------------------------------------------------------------------------------------------------------- def fetchdata(self): if (self.verbose): - print('Create local fix dir: ', self.targetdir) + print('Create local fix dir: {self.targetdir}') path = Path(self.targetdir) path.mkdir(parents=True, exist_ok=True) @@ -149,28 +149,28 @@ def fetchdata(self): # ---------------------------------------------------------------------------------------------------------------- def fetch_dir(self, dir): - remotedir = '%s/%s' %(self.aws_fix_bucket, dir) - localdir = '%s/%s' %( self.targetdir, dir ) - cmd = '%s %s %s' %(self.aws_sync, remotedir, localdir) + remotedir = f'{self.aws_fix_bucket}/{dir}' + localdir = f'{self.targetdir}/{dir}' + cmd = f'{self.aws_sync} {remotedir} {localdir}' self.download_dir(cmd, localdir) # ---------------------------------------------------------------------------------------------------------------- def download_dir(self, cmd, localdir): - #returned_value = os.system(cmd) # returns the exit code in unix - #print('returned value:', returned_value) + # returned_value = os.system(cmd) # returns the exit code in unix + # print('returned value:', returned_value) if (os.path.isdir(localdir)): - print('%s already exist. skip' %(localdir)) + print(f'{localdir} already exist. skip' else: parentdir, dirname = os.path.split(localdir) if (self.verbose): - print('Create local %s dir: ' %(parentdir)) + print(f'Create local {parentdir} dir:') path = Path(parentdir) path.mkdir(parents=True, exist_ok=True) if (self.verbose): print(cmd) - print('Downloading ', localdir) + print(f'Downloading {localdir}') returned_value = subprocess.call(cmd, shell=True) # returns the exit code in unix if (self.verbose): print('returned value:', returned_value) @@ -178,26 +178,26 @@ def download_dir(self, cmd, localdir): # ---------------------------------------------------------------------------------------------------------------- def fetch_ugwp_limb_tau(self): - ugwp_limb_tau_remotepath = '%s/ugwd/%s/ugwp_limb_tau.nc' %(self.aws_fix_bucket, self.fix_ver_dict['ugwd_ver']) - ugwp_limb_tau_localdir = '%s/ugwd/%s' %(self.targetdir, self.fix_ver_dict['ugwd_ver']) - filename = '%s/ugwp_limb_tau.nc' %(ugwp_limb_tau_localdir) + ugwp_limb_tau_remotepath = f'{self.aws_fix_bucket}/ugwd/{self.fix_ver_dict['ugwd_ver']}/ugwp_limb_tau.nc' + ugwp_limb_tau_localdir = f'{self.targetdir}/ugwd/{self.fix_ver_dict['ugwd_ver']}' + filename = f'{ugwp_limb_tau_localdir}/ugwp_limb_tau.nc' path = Path(ugwp_limb_tau_localdir) path.mkdir(parents=True, exist_ok=True) - cmd = '%s %s %s'%(self.aws_cp, ugwp_limb_tau_remotepath, filename) + cmd = f'{self.aws_cp} {ugwp_limb_tau_remotepath} {filename}' self.download_file(cmd, filename) # ---------------------------------------------------------------------------------------------------------------- def download_file(self, cmd, filename): - #returned_value = os.system(cmd) # returns the exit code in unix - #print('returned value:', returned_value) + # returned_value = os.system(cmd) # returns the exit code in unix + # print('returned value:', returned_value) if (os.path.isfile(filename)): - print('%s already exist. skip' %( filename )) + print(f'{filename} already exist. skip') else: if (self.verbose): print(cmd) - print('Downloading ', filename) + print(f'Downloading {filename}') returned_value = subprocess.call(cmd, shell=True) # returns the exit code in unix if (self.verbose): print('returned value:', returned_value) @@ -205,7 +205,7 @@ def download_file(self, cmd, filename): # ---------------------------------------------------------------------------------------------------------------- def set_fix_ver_from_gwhome(self, gwhome, verdict): - fix_ver_file = '%s/versions/fix.ver' + fix_ver_file = f'{gwhome}/versions/fix.ver' self.fix_ver_dict = verdict if (os.path.isfile(fix_ver_file)): with open(fix_ver_file, "r") as file: @@ -215,7 +215,7 @@ def set_fix_ver_from_gwhome(self, gwhome, verdict): exphead, _, key = headstr.partition(' ') self.fix_ver_dict[key] = value else: - print('fix_ver_file: %s does not exist.' %(fix_ver_file)) + print(f'fix_ver_file: {ix_ver_file}s does not exist.') # ---------------------------------------------------------------------------------------------------------------- def set_default_fix_ver(self, verdict): @@ -225,6 +225,7 @@ def set_default_fix_ver(self, verdict): # ---------------------------------------------------------------------------------------------------------------- def print_usage(verdict): + print('Usage: python fetch-fix-data.py \\') print(' --atmgrid=AtmospericGrid (for multiple grids, separate with ",") \\') print(' --ocngrid=OceanGrid (for multiple grids, separate with ",") \\') @@ -234,11 +235,12 @@ def print_usage(verdict): print('\t--gwhome=xxxx (Global-Workflow directory)') for key in verdict.keys(): - print( '\t--%s=yyyymmdd default: %s' %( key, verdict[key] ) ) + print(f'\t--{key}=yyyymmdd default: {verdict[key]}') # ---------------------------------------------------------------------------------------------------------------- if __name__ == '__main__': + atmgridlist = ['C48', 'C96', 'C192', 'C384', 'C768', 'C1152'] ocngridlist = ['500', '100', '050', '025'] @@ -247,7 +249,7 @@ def print_usage(verdict): ocngrid = '500' localdir = '/contrib/global-workflow-shared-data' - #default fix-version + # default fix-version verdict = {} verdict['aer_ver'] = '20220805' verdict['am_ver'] = '20220805' @@ -266,7 +268,7 @@ def print_usage(verdict): verdict['verif_ver'] = '20220805' verdict['wave_ver'] = '20240105' - gwhome=None + gwhome = None opts, args = getopt.getopt(sys.argv[1:], '', ['help', 'atmgrid=', 'ocngrid=', 'verbose=', 'localdir=', @@ -288,7 +290,7 @@ def print_usage(verdict): 'verif_ver=', 'wave_ver=']) for o, a in opts: - #print( 'o: %s, a: %s' %(o, a) ) + # print(f'o: {o}, a: {a}') if o in ['--help']: print_usage(verdict) sys.exit(0) @@ -304,7 +306,7 @@ def print_usage(verdict): gwhome = a else: _, vername = o.split('--') - print( 'vername: <%s>' %(vername) ) + print(f'vername: <{vername}>') verdict[vername] = a if (atmgrid.find(',') > 0): From 0284fb7f3128c750d8df0b05400d3d754491246e Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Wed, 26 Feb 2025 23:00:23 +0000 Subject: [PATCH 07/44] fix pynorm error 5 --- ush/fetch-fix-data.py | 240 +++++++++++++++++++++--------------------- 1 file changed, 121 insertions(+), 119 deletions(-) diff --git a/ush/fetch-fix-data.py b/ush/fetch-fix-data.py index fe7120285e1..6d6f8ac4fe6 100644 --- a/ush/fetch-fix-data.py +++ b/ush/fetch-fix-data.py @@ -13,16 +13,17 @@ # ---------------------------------------------------------------------------------------------------------------- class FetchFIXdata(): + def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], localdir=None, verbose=0): - self.aws_fix_bucket = 's3://noaa-nws-global-pds/fix' - self.aws_cp = 'aws --no-sign-request s3 cp' - self.aws_sync = 'aws --no-sign-request s3 sync' + self.aws_fix_bucket='s3://noaa-nws-global-pds/fix' + self.aws_cp='aws --no-sign-request s3 cp' + self.aws_sync='aws --no-sign-request s3 sync' - self.atmgridarray = atmgridarray - self.ocngridarray = ocngridarray - self.localdir = localdir - self.verbose = verbose + self.atmgridarray=atmgridarray + self.ocngridarray=ocngridarray + self.localdir=localdir + self.verbose=verbose # if (os.path.isdir(localdir)): # print('Prepare to download FIX data for %s and %s to %s' %(atmgrid, ocngrid, localdir)) @@ -30,14 +31,14 @@ def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], localdir=None, ve # print(f'local dir: <{localdir}> does not exist. Stop') # sys.exit(-1) - self.verdict = {} - self.s3dict = {} - self.s3dict['raworog'] = 'raw/orog' + self.verdict={} + self.s3dict={} + self.s3dict['raworog']='raw/orog' if (self.localdir.find('fix') < 0): - self.targetdir = f'{self.localdir}/fix.subset' + self.targetdir=f'{self.localdir}/fix.subset' else: - self.targetdir = self.localdir + self.targetdir=self.localdir # ---------------------------------------------------------------------------------------------------------------- def update_s3dict(self): @@ -52,41 +53,41 @@ def update_s3dict(self): def update_s3dick_grid_independent(self): for key in self.fix_ver_dict.keys(): - val = self.fix_ver_dict[key] + val=self.fix_ver_dict[key] if (key == 'aer_ver'): - self.s3dict['aer'] = f'aer/{val}' + self.s3dict['aer']=f'aer/{val}' elif ( key == 'am_ver'): - self.s3dict['am'] = f'am/{val}' + self.s3dict['am']=f'am/{val}' elif (key == 'chem_ver'): - self.s3dict['fimdata_chem'] = f'chem/{val}/fimdata_chem' - self.s3dict['Emission_data'] = f'chem/{val}/Emission_data' + self.s3dict['fimdata_chem']=f'chem/{val}/fimdata_chem' + self.s3dict['Emission_data']=f'chem/{val}/Emission_data' elif (key == 'datm_ver'): - self.s3dict['cfsr'] = f'datm/{val}/cfsr' - self.s3dict['gefs'] = f'datm/{val}/gefs' - self.s3dict['gfs'] = f'datm/{val}/gfs' - self.s3dict['mom6'] = f'datm/{val}/mom6' + self.s3dict['cfsr']=f'datm/{val}/cfsr' + self.s3dict['gefs']=f'datm/{val}/gefs' + self.s3dict['gfs']=f'datm/{val}/gfs' + self.s3dict['mom6']=f'datm/{val}/mom6' elif (key == 'glwu_ver'): - self.s3dict['glwu'] = f'glwu/{val}' + self.s3dict['glwu']=f'glwu/{val}' elif (key == 'gsi_ver'): - self.s3dict['gsi'] = f'gsi/{val}' + self.s3dict['gsi']=f'gsi/{val}' elif (key == 'lut_ver'): - self.s3dict['lut'] = f'lut/{val}' + self.s3dict['lut']=f'lut/{val}' elif (key == 'mom6_ver'): - self.s3dict['mom6post'] = f'mom6/{val}/post' + self.s3dict['mom6post']=f'mom6/{val}/post' elif (key == 'reg2grb2_ver'): - self.s3dict['reg2grb2'] = f'reg2grb2/{val}' + self.s3dict['reg2grb2']=f'reg2grb2/{val}' elif (key == 'sfc_climb_ver' ): - self.s3dict['sfc_climo'] = f'sfc_climo/{val}' + self.s3dict['sfc_climo']=f'sfc_climo/{val}' elif (key == 'verif_ver'): - self.s3dict['verif'] = f'verif/{val}' + self.s3dict['verif']=f'verif/{val}' elif (key == 'wave_ver'): - self.s3dict['wave'] = f'wave/{val}' + self.s3dict['wave']=f'wave/{val}' # ---------------------------------------------------------------------------------------------------------------- def add_grid_data(self): for key in self.fix_ver_dict.keys(): - val = self.fix_ver_dict[key] + val=self.fix_ver_dict[key] if (key == 'orog_ver'): self.add_atmgrid2s3dict('orog', key, val) elif (key == 'ugwd_ver'): @@ -102,23 +103,23 @@ def add_grid_data(self): def add_atmgrid2s3dict(self, varname, key, val): for atmgrid in self.atmgridarray: - newkey = f'{key}_{atmgrid}' - self.s3dict[newkey] = f'{varname}/{val}/{atmgrid}' + newkey=f'{key}_{atmgrid}' + self.s3dict[newkey]=f'{varname}/{val}/{atmgrid}' # ---------------------------------------------------------------------------------------------------------------- def add_ocngrid2s3dict(self, varname, key, val): for ocngrid in self.ocngridarray: - newkey = f'{key}_{atmgrid}' - self.s3dict[newkey] = f'{varname}/{val}/{ocngrid}' + newkey=f'{key}_{atmgrid}' + self.s3dict[newkey]=f'{varname}/{val}/{ocngrid}' # ---------------------------------------------------------------------------------------------------------------- def add_cpl2s3dict(self, varname, key, val): for atmgrid in self.atmgridarray: for ocngrid in self.ocngridarray: - newkey = f'{key}_a{atmgrid}o{ocngrid}' - self.s3dict[newkey] = f'{varname}/{val}/a{atmgrid}o{ocngrid}' + newkey=f'{key}_a{atmgrid}o{ocngrid}' + self.s3dict[newkey]=f'{varname}/{val}/a{atmgrid}o{ocngrid}' # ---------------------------------------------------------------------------------------------------------------- def printinfo(self): @@ -129,7 +130,7 @@ def printinfo(self): print(f'From: {self.aws_fix_bucket}') print(f'To: {self.targetdir}') for key in self.s3dict.keys(): - val = self.s3dict[key] + val=self.s3dict[key] print(f'{key}: {val}') # ---------------------------------------------------------------------------------------------------------------- @@ -138,7 +139,7 @@ def fetchdata(self): if (self.verbose): print('Create local fix dir: {self.targetdir}') - path = Path(self.targetdir) + path=Path(self.targetdir) path.mkdir(parents=True, exist_ok=True) self.fetch_ugwp_limb_tau() @@ -149,47 +150,47 @@ def fetchdata(self): # ---------------------------------------------------------------------------------------------------------------- def fetch_dir(self, dir): - remotedir = f'{self.aws_fix_bucket}/{dir}' - localdir = f'{self.targetdir}/{dir}' - cmd = f'{self.aws_sync} {remotedir} {localdir}' + remotedir=f'{self.aws_fix_bucket}/{dir}' + localdir=f'{self.targetdir}/{dir}' + cmd=f'{self.aws_sync} {remotedir} {localdir}' self.download_dir(cmd, localdir) # ---------------------------------------------------------------------------------------------------------------- def download_dir(self, cmd, localdir): - # returned_value = os.system(cmd) # returns the exit code in unix + # returned_value=os.system(cmd) # returns the exit code in unix # print('returned value:', returned_value) if (os.path.isdir(localdir)): print(f'{localdir} already exist. skip' else: - parentdir, dirname = os.path.split(localdir) + parentdir, dirname=os.path.split(localdir) if (self.verbose): print(f'Create local {parentdir} dir:') - path = Path(parentdir) + path=Path(parentdir) path.mkdir(parents=True, exist_ok=True) if (self.verbose): print(cmd) print(f'Downloading {localdir}') - returned_value = subprocess.call(cmd, shell=True) # returns the exit code in unix + returned_value=subprocess.call(cmd, shell=True) # returns the exit code in unix if (self.verbose): print('returned value:', returned_value) # ---------------------------------------------------------------------------------------------------------------- def fetch_ugwp_limb_tau(self): - ugwp_limb_tau_remotepath = f'{self.aws_fix_bucket}/ugwd/{self.fix_ver_dict['ugwd_ver']}/ugwp_limb_tau.nc' - ugwp_limb_tau_localdir = f'{self.targetdir}/ugwd/{self.fix_ver_dict['ugwd_ver']}' - filename = f'{ugwp_limb_tau_localdir}/ugwp_limb_tau.nc' - path = Path(ugwp_limb_tau_localdir) + ugwp_limb_tau_remotepath=f'{self.aws_fix_bucket}/ugwd/{self.fix_ver_dict['ugwd_ver']}/ugwp_limb_tau.nc' + ugwp_limb_tau_localdir=f'{self.targetdir}/ugwd/{self.fix_ver_dict['ugwd_ver']}' + filename=f'{ugwp_limb_tau_localdir}/ugwp_limb_tau.nc' + path=Path(ugwp_limb_tau_localdir) path.mkdir(parents=True, exist_ok=True) - cmd = f'{self.aws_cp} {ugwp_limb_tau_remotepath} {filename}' + cmd=f'{self.aws_cp} {ugwp_limb_tau_remotepath} {filename}' self.download_file(cmd, filename) # ---------------------------------------------------------------------------------------------------------------- def download_file(self, cmd, filename): - # returned_value = os.system(cmd) # returns the exit code in unix + # returned_value=os.system(cmd) # returns the exit code in unix # print('returned value:', returned_value) if (os.path.isfile(filename)): @@ -198,29 +199,29 @@ def download_file(self, cmd, filename): if (self.verbose): print(cmd) print(f'Downloading {filename}') - returned_value = subprocess.call(cmd, shell=True) # returns the exit code in unix + returned_value= subprocess.call(cmd, shell=True) # returns the exit code in unix if (self.verbose): print('returned value:', returned_value) - # ---------------------------------------------------------------------------------------------------------------- + # -------------------------------------------------------------------------------------------------------------- def set_fix_ver_from_gwhome(self, gwhome, verdict): - fix_ver_file = f'{gwhome}/versions/fix.ver' - self.fix_ver_dict = verdict + fix_ver_file=f'{gwhome}/versions/fix.ver' + self.fix_ver_dict=verdict if (os.path.isfile(fix_ver_file)): with open(fix_ver_file, "r") as file: for line in file.readlines(): if (line.find('export ') >= 0): - headstr, _, value = line.strip().partition('=') - exphead, _, key = headstr.partition(' ') - self.fix_ver_dict[key] = value + headstr, _, value=line.strip().partition('=') + exphead, _, key=headstr.partition(' ') + self.fix_ver_dict[key]=value else: print(f'fix_ver_file: {ix_ver_file}s does not exist.') - # ---------------------------------------------------------------------------------------------------------------- + # -------------------------------------------------------------------------------------------------------------- def set_default_fix_ver(self, verdict): - self.fix_ver_dict = verdict + self.fix_ver_dict=verdict # ---------------------------------------------------------------------------------------------------------------- def print_usage(verdict): @@ -241,78 +242,78 @@ def print_usage(verdict): if __name__ == '__main__': - atmgridlist = ['C48', 'C96', 'C192', 'C384', 'C768', 'C1152'] - ocngridlist = ['500', '100', '050', '025'] + atmgridlist=['C48', 'C96', 'C192', 'C384', 'C768', 'C1152'] + ocngridlist=['500', '100', '050', '025'] - verbose = 0 - atmgrid = 'C48' - ocngrid = '500' - localdir = '/contrib/global-workflow-shared-data' + verbose=0 + atmgrid='C48' + ocngrid='500' + localdir='/contrib/global-workflow-shared-data' # default fix-version - verdict = {} - verdict['aer_ver'] = '20220805' - verdict['am_ver'] = '20220805' - verdict['chem_ver'] = '20220805' - verdict['cice_ver'] = '20240416' - verdict['cpl_ver'] = '20230526' - verdict['datm_ver'] = '20220805' - verdict['glwu_ver'] = '20220805' - verdict['gsi_ver'] = '20240208' - verdict['lut_ver'] = '20220805' - verdict['mom6_ver'] = '20240416' - verdict['orog_ver'] = '20231027' - verdict['reg2grb2_ver'] = '20220805' - verdict['sfc_climo_ver'] = '20220805' - verdict['ugwd_ver'] = '20240624' - verdict['verif_ver'] = '20220805' - verdict['wave_ver'] = '20240105' - - gwhome = None - - opts, args = getopt.getopt(sys.argv[1:], '', ['help', 'atmgrid=', 'ocngrid=', - 'verbose=', 'localdir=', - 'gwhome=', - 'aer_ver=', - 'am_ver=', - 'chem_ver=', - 'cice_ver=', - 'cpl_ver=', - 'datm_ver=', - 'glwu_ver=', - 'gsi_ver=', - 'lut_ver=', - 'mom6_ver=', - 'orog_ver=', - 'reg2grb2_ver=', - 'sfc_climo_ver=', - 'ugwd_ver=', - 'verif_ver=', - 'wave_ver=']) + verdict={} + verdict['aer_ver']='20220805' + verdict['am_ver']='20220805' + verdict['chem_ver']='20220805' + verdict['cice_ver']='20240416' + verdict['cpl_ver']='20230526' + verdict['datm_ver']='20220805' + verdict['glwu_ver']='20220805' + verdict['gsi_ver']='20240208' + verdict['lut_ver']='20220805' + verdict['mom6_ver']='20240416' + verdict['orog_ver']='20231027' + verdict['reg2grb2_ver']='20220805' + verdict['sfc_climo_ver']='20220805' + verdict['ugwd_ver']='20240624' + verdict['verif_ver']='20220805' + verdict['wave_ver']='20240105' + + gwhome=None + + opts, args=getopt.getopt(sys.argv[1:], '', ['help', 'atmgrid=', 'ocngrid=', + 'verbose=', 'localdir=', + 'gwhome=', + 'aer_ver=', + 'am_ver=', + 'chem_ver=', + 'cice_ver=', + 'cpl_ver=', + 'datm_ver=', + 'glwu_ver=', + 'gsi_ver=', + 'lut_ver=', + 'mom6_ver=', + 'orog_ver=', + 'reg2grb2_ver=', + 'sfc_climo_ver=', + 'ugwd_ver=', + 'verif_ver=', + 'wave_ver=']) for o, a in opts: # print(f'o: {o}, a: {a}') if o in ['--help']: print_usage(verdict) sys.exit(0) elif o in ['--verbose']: - verbose = int(a) + verbose=int(a) elif o in ['--atmgrid']: - atmgrid = a + atmgrid=a elif o in ['--ocngrid']: - ocngrid = a + ocngrid=a elif o in ['--localdir']: - localdir = a + localdir=a elif o in ['--gwhome']: - gwhome = a + gwhome=a else: - _, vername = o.split('--') + _, vername=o.split('--') print(f'vername: <{vername}>') - verdict[vername] = a + verdict[vername]=a if (atmgrid.find(',') > 0): - atmgridarray = atmgrid.split(',') + atmgridarray=atmgrid.split(',') else: - atmgridarray = [atmgrid] + atmgridarray=[atmgrid] for grid in atmgridarray: if (grid not in atmgridlist): @@ -322,9 +323,9 @@ def print_usage(verdict): sys.exit(-1) if (ocngrid.find(',') > 0): - ocngridarray = ocngrid.split(',') + ocngridarray=ocngrid.split(',') else: - ocngridarray = [ocngrid] + ocngridarray=[ocngrid] for grid in ocngridarray: if (grid not in ocngridlist): @@ -334,9 +335,9 @@ def print_usage(verdict): sys.exit(-1) # ------------------------------------------------------------------ - ffd = FetchFIXdata(atmgridarray=atmgridarray, - ocngridarray=ocngridarray, - localdir=localdir, verbose=verbose) + ffd=FetchFIXdata(atmgridarray=atmgridarray, + ocngridarray=ocngridarray, + localdir=localdir, verbose=verbose) if (gwhome is None): ffd.set_default_fix_ver(verdict) @@ -346,3 +347,4 @@ def print_usage(verdict): ffd.update_s3dict() ffd.fetchdata() + From 27ca2f17f70b35280a96ffb919d6c819f609eaf4 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Wed, 26 Feb 2025 23:10:55 +0000 Subject: [PATCH 08/44] fix pynorm error 6 --- ush/fetch-fix-data.py | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/ush/fetch-fix-data.py b/ush/fetch-fix-data.py index 6d6f8ac4fe6..34df3b19ba5 100644 --- a/ush/fetch-fix-data.py +++ b/ush/fetch-fix-data.py @@ -10,13 +10,13 @@ import subprocess from pathlib import Path -# ---------------------------------------------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ class FetchFIXdata(): def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], localdir=None, verbose=0): - self.aws_fix_bucket='s3://noaa-nws-global-pds/fix' + self.aws_fix_bucket= 's3://noaa-nws-global-pds/fix' self.aws_cp='aws --no-sign-request s3 cp' self.aws_sync='aws --no-sign-request s3 sync' @@ -40,7 +40,7 @@ def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], localdir=None, ve else: self.targetdir=self.localdir - # ---------------------------------------------------------------------------------------------------------------- + # -------------------------------------------------------------------------- def update_s3dict(self): self.update_s3dick_grid_independent() @@ -49,14 +49,14 @@ def update_s3dict(self): if (self.verbose): self.printinfo() - # ---------------------------------------------------------------------------------------------------------------- + # -------------------------------------------------------------------------- def update_s3dick_grid_independent(self): for key in self.fix_ver_dict.keys(): val=self.fix_ver_dict[key] if (key == 'aer_ver'): self.s3dict['aer']=f'aer/{val}' - elif ( key == 'am_ver'): + elif (key == 'am_ver'): self.s3dict['am']=f'am/{val}' elif (key == 'chem_ver'): self.s3dict['fimdata_chem']=f'chem/{val}/fimdata_chem' @@ -76,14 +76,14 @@ def update_s3dick_grid_independent(self): self.s3dict['mom6post']=f'mom6/{val}/post' elif (key == 'reg2grb2_ver'): self.s3dict['reg2grb2']=f'reg2grb2/{val}' - elif (key == 'sfc_climb_ver' ): + elif (key == 'sfc_climb_ver'): self.s3dict['sfc_climo']=f'sfc_climo/{val}' elif (key == 'verif_ver'): self.s3dict['verif']=f'verif/{val}' elif (key == 'wave_ver'): self.s3dict['wave']=f'wave/{val}' - # ---------------------------------------------------------------------------------------------------------------- + # -------------------------------------------------------------------------- def add_grid_data(self): for key in self.fix_ver_dict.keys(): @@ -99,21 +99,21 @@ def add_grid_data(self): elif (key == 'cpl_ver'): self.add_cpl2s3dict('cpl', key, val) - # ---------------------------------------------------------------------------------------------------------------- + # -------------------------------------------------------------------------- def add_atmgrid2s3dict(self, varname, key, val): for atmgrid in self.atmgridarray: newkey=f'{key}_{atmgrid}' self.s3dict[newkey]=f'{varname}/{val}/{atmgrid}' - # ---------------------------------------------------------------------------------------------------------------- + # ------------------------------------------------------------------------- def add_ocngrid2s3dict(self, varname, key, val): for ocngrid in self.ocngridarray: newkey=f'{key}_{atmgrid}' self.s3dict[newkey]=f'{varname}/{val}/{ocngrid}' - # ---------------------------------------------------------------------------------------------------------------- + # ------------------------------------------------------------------------- def add_cpl2s3dict(self, varname, key, val): for atmgrid in self.atmgridarray: @@ -121,7 +121,7 @@ def add_cpl2s3dict(self, varname, key, val): newkey=f'{key}_a{atmgrid}o{ocngrid}' self.s3dict[newkey]=f'{varname}/{val}/a{atmgrid}o{ocngrid}' - # ---------------------------------------------------------------------------------------------------------------- + # ------------------------------------------------------------------------- def printinfo(self): print(f'Preparing to fetch') @@ -133,7 +133,7 @@ def printinfo(self): val=self.s3dict[key] print(f'{key}: {val}') - # ---------------------------------------------------------------------------------------------------------------- + # ------------------------------------------------------------------------- def fetchdata(self): if (self.verbose): @@ -147,7 +147,7 @@ def fetchdata(self): for key in self.s3dict.keys(): self.fetch_dir(self.s3dict[key]) - # ---------------------------------------------------------------------------------------------------------------- + # ------------------------------------------------------------------------- def fetch_dir(self, dir): remotedir=f'{self.aws_fix_bucket}/{dir}' @@ -155,7 +155,7 @@ def fetch_dir(self, dir): cmd=f'{self.aws_sync} {remotedir} {localdir}' self.download_dir(cmd, localdir) - # ---------------------------------------------------------------------------------------------------------------- + # -------------------------------------------------------------------------- def download_dir(self, cmd, localdir): # returned_value=os.system(cmd) # returns the exit code in unix @@ -176,7 +176,7 @@ def download_dir(self, cmd, localdir): if (self.verbose): print('returned value:', returned_value) - # ---------------------------------------------------------------------------------------------------------------- + # -------------------------------------------------------------------------- def fetch_ugwp_limb_tau(self): ugwp_limb_tau_remotepath=f'{self.aws_fix_bucket}/ugwd/{self.fix_ver_dict['ugwd_ver']}/ugwp_limb_tau.nc' @@ -187,7 +187,7 @@ def fetch_ugwp_limb_tau(self): cmd=f'{self.aws_cp} {ugwp_limb_tau_remotepath} {filename}' self.download_file(cmd, filename) - # ---------------------------------------------------------------------------------------------------------------- + # ------------------------------------------------------------------------- def download_file(self, cmd, filename): # returned_value=os.system(cmd) # returns the exit code in unix @@ -199,11 +199,11 @@ def download_file(self, cmd, filename): if (self.verbose): print(cmd) print(f'Downloading {filename}') - returned_value= subprocess.call(cmd, shell=True) # returns the exit code in unix + returned_value=subprocess.call(cmd, shell=True) # returns the exit code in unix if (self.verbose): print('returned value:', returned_value) - # -------------------------------------------------------------------------------------------------------------- + # -------------------------------------------------------------------------- def set_fix_ver_from_gwhome(self, gwhome, verdict): fix_ver_file=f'{gwhome}/versions/fix.ver' @@ -218,12 +218,12 @@ def set_fix_ver_from_gwhome(self, gwhome, verdict): else: print(f'fix_ver_file: {ix_ver_file}s does not exist.') - # -------------------------------------------------------------------------------------------------------------- + # ------------------------------------------------------------------------ def set_default_fix_ver(self, verdict): self.fix_ver_dict=verdict -# ---------------------------------------------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- def print_usage(verdict): @@ -238,7 +238,7 @@ def print_usage(verdict): for key in verdict.keys(): print(f'\t--{key}=yyyymmdd default: {verdict[key]}') -# ---------------------------------------------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ if __name__ == '__main__': @@ -347,4 +347,3 @@ def print_usage(verdict): ffd.update_s3dict() ffd.fetchdata() - From f39bfd9f4290a08a7b69955e7f61ff2681f3f39e Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Thu, 27 Feb 2025 00:18:28 +0000 Subject: [PATCH 09/44] fix pynorm error 7 --- ush/fetch-fix-data.py | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/ush/fetch-fix-data.py b/ush/fetch-fix-data.py index 34df3b19ba5..7bd90026aa1 100644 --- a/ush/fetch-fix-data.py +++ b/ush/fetch-fix-data.py @@ -13,17 +13,16 @@ # ------------------------------------------------------------------------------ class FetchFIXdata(): - def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], localdir=None, verbose=0): - self.aws_fix_bucket= 's3://noaa-nws-global-pds/fix' - self.aws_cp='aws --no-sign-request s3 cp' - self.aws_sync='aws --no-sign-request s3 sync' + self.aws_fix_bucket= f's3://noaa-nws-global-pds/fix' + self.aws_cp = f'aws --no-sign-request s3 cp' + self.aws_sync = f'aws --no-sign-request s3 sync' - self.atmgridarray=atmgridarray - self.ocngridarray=ocngridarray - self.localdir=localdir - self.verbose=verbose + self.atmgridarray = atmgridarray + self.ocngridarray = ocngridarray + self.localdir = localdir + self.verbose = verbose # if (os.path.isdir(localdir)): # print('Prepare to download FIX data for %s and %s to %s' %(atmgrid, ocngrid, localdir)) @@ -31,14 +30,14 @@ def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], localdir=None, ve # print(f'local dir: <{localdir}> does not exist. Stop') # sys.exit(-1) - self.verdict={} - self.s3dict={} - self.s3dict['raworog']='raw/orog' + self.verdict = {} + self.s3dict = {} + self.s3dict['raworog'] = f'raw/orog' if (self.localdir.find('fix') < 0): - self.targetdir=f'{self.localdir}/fix.subset' + self.targetdir = f'{self.localdir}/fix.subset' else: - self.targetdir=self.localdir + self.targetdir = self.localdir # -------------------------------------------------------------------------- def update_s3dict(self): @@ -118,8 +117,8 @@ def add_cpl2s3dict(self, varname, key, val): for atmgrid in self.atmgridarray: for ocngrid in self.ocngridarray: - newkey=f'{key}_a{atmgrid}o{ocngrid}' - self.s3dict[newkey]=f'{varname}/{val}/a{atmgrid}o{ocngrid}' + newkey = f'{key}_a{atmgrid}o{ocngrid}' + self.s3dict[newkey] = f'{varname}/{val}/a{atmgrid}o{ocngrid}' # ------------------------------------------------------------------------- def printinfo(self): @@ -137,13 +136,13 @@ def printinfo(self): def fetchdata(self): if (self.verbose): - print('Create local fix dir: {self.targetdir}') + print(f'Create local fix dir: {self.targetdir}') path=Path(self.targetdir) path.mkdir(parents=True, exist_ok=True) self.fetch_ugwp_limb_tau() - + for key in self.s3dict.keys(): self.fetch_dir(self.s3dict[key]) @@ -162,7 +161,7 @@ def download_dir(self, cmd, localdir): # print('returned value:', returned_value) if (os.path.isdir(localdir)): - print(f'{localdir} already exist. skip' + print(f'{localdir} already exist. skip') else: parentdir, dirname=os.path.split(localdir) if (self.verbose): @@ -190,8 +189,8 @@ def fetch_ugwp_limb_tau(self): # ------------------------------------------------------------------------- def download_file(self, cmd, filename): - # returned_value=os.system(cmd) # returns the exit code in unix - # print('returned value:', returned_value) + # returned_value=os.system(cmd) # returns the exit code in unix + # print('returned value:', returned_value) if (os.path.isfile(filename)): print(f'{filename} already exist. skip') @@ -226,7 +225,6 @@ def set_default_fix_ver(self, verdict): # ----------------------------------------------------------------------------- def print_usage(verdict): - print('Usage: python fetch-fix-data.py \\') print(' --atmgrid=AtmospericGrid (for multiple grids, separate with ",") \\') print(' --ocngrid=OceanGrid (for multiple grids, separate with ",") \\') @@ -241,7 +239,6 @@ def print_usage(verdict): # ------------------------------------------------------------------------------ if __name__ == '__main__': - atmgridlist=['C48', 'C96', 'C192', 'C384', 'C768', 'C1152'] ocngridlist=['500', '100', '050', '025'] @@ -345,5 +342,4 @@ def print_usage(verdict): ffd.set_fix_ver_from_gwhome(gwhome, verdict) ffd.update_s3dict() - ffd.fetchdata() From 8f7fc23bfc7b2cec2f4b0cab7aa87d9b1417a2d7 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Thu, 27 Feb 2025 00:26:42 +0000 Subject: [PATCH 10/44] fix pynorm error 8 --- ush/fetch-fix-data.py | 211 +++++++++++++++++++++--------------------- 1 file changed, 107 insertions(+), 104 deletions(-) diff --git a/ush/fetch-fix-data.py b/ush/fetch-fix-data.py index 7bd90026aa1..97a649443bb 100644 --- a/ush/fetch-fix-data.py +++ b/ush/fetch-fix-data.py @@ -13,9 +13,10 @@ # ------------------------------------------------------------------------------ class FetchFIXdata(): + def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], localdir=None, verbose=0): - self.aws_fix_bucket= f's3://noaa-nws-global-pds/fix' + self.aws_fix_bucket = f's3://noaa-nws-global-pds/fix' self.aws_cp = f'aws --no-sign-request s3 cp' self.aws_sync = f'aws --no-sign-request s3 sync' @@ -52,41 +53,41 @@ def update_s3dict(self): def update_s3dick_grid_independent(self): for key in self.fix_ver_dict.keys(): - val=self.fix_ver_dict[key] + val = self.fix_ver_dict[key] if (key == 'aer_ver'): - self.s3dict['aer']=f'aer/{val}' + self.s3dict['aer'] = f'aer/{val}' elif (key == 'am_ver'): - self.s3dict['am']=f'am/{val}' + self.s3dict['am'] = f'am/{val}' elif (key == 'chem_ver'): - self.s3dict['fimdata_chem']=f'chem/{val}/fimdata_chem' - self.s3dict['Emission_data']=f'chem/{val}/Emission_data' + self.s3dict['fimdata_chem'] = f'chem/{val}/fimdata_chem' + self.s3dict['Emission_data'] = f'chem/{val}/Emission_data' elif (key == 'datm_ver'): - self.s3dict['cfsr']=f'datm/{val}/cfsr' - self.s3dict['gefs']=f'datm/{val}/gefs' - self.s3dict['gfs']=f'datm/{val}/gfs' - self.s3dict['mom6']=f'datm/{val}/mom6' + self.s3dict['cfsr'] = f'datm/{val}/cfsr' + self.s3dict['gefs'] = f'datm/{val}/gefs' + self.s3dict['gfs'] = f'datm/{val}/gfs' + self.s3dict['mom6'] = f'datm/{val}/mom6' elif (key == 'glwu_ver'): - self.s3dict['glwu']=f'glwu/{val}' + self.s3dict['glwu'] = f'glwu/{val}' elif (key == 'gsi_ver'): - self.s3dict['gsi']=f'gsi/{val}' + self.s3dict['gsi'] = f'gsi/{val}' elif (key == 'lut_ver'): - self.s3dict['lut']=f'lut/{val}' + self.s3dict['lut'] = f'lut/{val}' elif (key == 'mom6_ver'): - self.s3dict['mom6post']=f'mom6/{val}/post' + self.s3dict['mom6post'] = f'mom6/{val}/post' elif (key == 'reg2grb2_ver'): - self.s3dict['reg2grb2']=f'reg2grb2/{val}' + self.s3dict['reg2grb2'] = f'reg2grb2/{val}' elif (key == 'sfc_climb_ver'): - self.s3dict['sfc_climo']=f'sfc_climo/{val}' + self.s3dict['sfc_climo'] = f'sfc_climo/{val}' elif (key == 'verif_ver'): - self.s3dict['verif']=f'verif/{val}' + self.s3dict['verif'] = f'verif/{val}' elif (key == 'wave_ver'): - self.s3dict['wave']=f'wave/{val}' + self.s3dict['wave'] = f'wave/{val}' # -------------------------------------------------------------------------- def add_grid_data(self): for key in self.fix_ver_dict.keys(): - val=self.fix_ver_dict[key] + val = self.fix_ver_dict[key] if (key == 'orog_ver'): self.add_atmgrid2s3dict('orog', key, val) elif (key == 'ugwd_ver'): @@ -102,15 +103,15 @@ def add_grid_data(self): def add_atmgrid2s3dict(self, varname, key, val): for atmgrid in self.atmgridarray: - newkey=f'{key}_{atmgrid}' - self.s3dict[newkey]=f'{varname}/{val}/{atmgrid}' + newkey = f'{key}_{atmgrid}' + self.s3dict[newkey] = f'{varname}/{val}/{atmgrid}' # ------------------------------------------------------------------------- def add_ocngrid2s3dict(self, varname, key, val): for ocngrid in self.ocngridarray: - newkey=f'{key}_{atmgrid}' - self.s3dict[newkey]=f'{varname}/{val}/{ocngrid}' + newkey = f'{key}_{atmgrid}' + self.s3dict[newkey] = f'{varname}/{val}/{ocngrid}' # ------------------------------------------------------------------------- def add_cpl2s3dict(self, varname, key, val): @@ -129,7 +130,7 @@ def printinfo(self): print(f'From: {self.aws_fix_bucket}') print(f'To: {self.targetdir}') for key in self.s3dict.keys(): - val=self.s3dict[key] + val = self.s3dict[key] print(f'{key}: {val}') # ------------------------------------------------------------------------- @@ -138,7 +139,7 @@ def fetchdata(self): if (self.verbose): print(f'Create local fix dir: {self.targetdir}') - path=Path(self.targetdir) + path = Path(self.targetdir) path.mkdir(parents=True, exist_ok=True) self.fetch_ugwp_limb_tau() @@ -149,47 +150,47 @@ def fetchdata(self): # ------------------------------------------------------------------------- def fetch_dir(self, dir): - remotedir=f'{self.aws_fix_bucket}/{dir}' - localdir=f'{self.targetdir}/{dir}' - cmd=f'{self.aws_sync} {remotedir} {localdir}' + remotedir = f'{self.aws_fix_bucket}/{dir}' + localdir = f'{self.targetdir}/{dir}' + cmd = f'{self.aws_sync} {remotedir} {localdir}' self.download_dir(cmd, localdir) # -------------------------------------------------------------------------- def download_dir(self, cmd, localdir): - # returned_value=os.system(cmd) # returns the exit code in unix + # returned_value = os.system(cmd) # returns the exit code in unix # print('returned value:', returned_value) if (os.path.isdir(localdir)): print(f'{localdir} already exist. skip') else: - parentdir, dirname=os.path.split(localdir) + parentdir, dirname = os.path.split(localdir) if (self.verbose): print(f'Create local {parentdir} dir:') - path=Path(parentdir) + path = Path(parentdir) path.mkdir(parents=True, exist_ok=True) if (self.verbose): print(cmd) print(f'Downloading {localdir}') - returned_value=subprocess.call(cmd, shell=True) # returns the exit code in unix + returned_value = subprocess.call(cmd, shell=True) # returns the exit code in unix if (self.verbose): print('returned value:', returned_value) # -------------------------------------------------------------------------- def fetch_ugwp_limb_tau(self): - ugwp_limb_tau_remotepath=f'{self.aws_fix_bucket}/ugwd/{self.fix_ver_dict['ugwd_ver']}/ugwp_limb_tau.nc' - ugwp_limb_tau_localdir=f'{self.targetdir}/ugwd/{self.fix_ver_dict['ugwd_ver']}' - filename=f'{ugwp_limb_tau_localdir}/ugwp_limb_tau.nc' - path=Path(ugwp_limb_tau_localdir) + ugwp_limb_tau_remotepath = f'{self.aws_fix_bucket}/ugwd/{self.fix_ver_dict['ugwd_ver']}/ugwp_limb_tau.nc' + ugwp_limb_tau_localdir = f'{self.targetdir}/ugwd/{self.fix_ver_dict['ugwd_ver']}' + filename = f'{ugwp_limb_tau_localdir}/ugwp_limb_tau.nc' + path = Path(ugwp_limb_tau_localdir) path.mkdir(parents=True, exist_ok=True) - cmd=f'{self.aws_cp} {ugwp_limb_tau_remotepath} {filename}' + cmd = f'{self.aws_cp} {ugwp_limb_tau_remotepath} {filename}' self.download_file(cmd, filename) # ------------------------------------------------------------------------- def download_file(self, cmd, filename): - # returned_value=os.system(cmd) # returns the exit code in unix + # returned_value = os.system(cmd) # returns the exit code in unix # print('returned value:', returned_value) if (os.path.isfile(filename)): @@ -198,33 +199,34 @@ def download_file(self, cmd, filename): if (self.verbose): print(cmd) print(f'Downloading {filename}') - returned_value=subprocess.call(cmd, shell=True) # returns the exit code in unix + returned_value = subprocess.call(cmd, shell=True) # returns the exit code in unix if (self.verbose): print('returned value:', returned_value) # -------------------------------------------------------------------------- def set_fix_ver_from_gwhome(self, gwhome, verdict): - fix_ver_file=f'{gwhome}/versions/fix.ver' - self.fix_ver_dict=verdict + fix_ver_file = f'{gwhome}/versions/fix.ver' + self.fix_ver_dict = verdict if (os.path.isfile(fix_ver_file)): with open(fix_ver_file, "r") as file: for line in file.readlines(): if (line.find('export ') >= 0): - headstr, _, value=line.strip().partition('=') - exphead, _, key=headstr.partition(' ') - self.fix_ver_dict[key]=value + headstr, _, value = line.strip().partition('=') + exphead, _, key = headstr.partition(' ') + self.fix_ver_dict[key] = value else: print(f'fix_ver_file: {ix_ver_file}s does not exist.') # ------------------------------------------------------------------------ def set_default_fix_ver(self, verdict): - self.fix_ver_dict=verdict + self.fix_ver_dict = verdict # ----------------------------------------------------------------------------- def print_usage(verdict): + print('Usage: python fetch-fix-data.py \\') print(' --atmgrid=AtmospericGrid (for multiple grids, separate with ",") \\') print(' --ocngrid=OceanGrid (for multiple grids, separate with ",") \\') @@ -239,78 +241,79 @@ def print_usage(verdict): # ------------------------------------------------------------------------------ if __name__ == '__main__': - atmgridlist=['C48', 'C96', 'C192', 'C384', 'C768', 'C1152'] - ocngridlist=['500', '100', '050', '025'] - verbose=0 - atmgrid='C48' - ocngrid='500' - localdir='/contrib/global-workflow-shared-data' + atmgridlist = ['C48', 'C96', 'C192', 'C384', 'C768', 'C1152'] + ocngridlist = ['500', '100', '050', '025'] + + verbose = 0 + atmgrid = f'C48' + ocngrid = f'500' + localdir = f'/contrib/global-workflow-shared-data' # default fix-version - verdict={} - verdict['aer_ver']='20220805' - verdict['am_ver']='20220805' - verdict['chem_ver']='20220805' - verdict['cice_ver']='20240416' - verdict['cpl_ver']='20230526' - verdict['datm_ver']='20220805' - verdict['glwu_ver']='20220805' - verdict['gsi_ver']='20240208' - verdict['lut_ver']='20220805' - verdict['mom6_ver']='20240416' - verdict['orog_ver']='20231027' - verdict['reg2grb2_ver']='20220805' - verdict['sfc_climo_ver']='20220805' - verdict['ugwd_ver']='20240624' - verdict['verif_ver']='20220805' - verdict['wave_ver']='20240105' - - gwhome=None - - opts, args=getopt.getopt(sys.argv[1:], '', ['help', 'atmgrid=', 'ocngrid=', - 'verbose=', 'localdir=', - 'gwhome=', - 'aer_ver=', - 'am_ver=', - 'chem_ver=', - 'cice_ver=', - 'cpl_ver=', - 'datm_ver=', - 'glwu_ver=', - 'gsi_ver=', - 'lut_ver=', - 'mom6_ver=', - 'orog_ver=', - 'reg2grb2_ver=', - 'sfc_climo_ver=', - 'ugwd_ver=', - 'verif_ver=', - 'wave_ver=']) + verdict = {} + verdict['aer_ver'] = f'20220805' + verdict['am_ver'] = f'20220805' + verdict['chem_ver'] = f'20220805' + verdict['cice_ver'] = f'20240416' + verdict['cpl_ver'] = f'20230526' + verdict['datm_ver'] = f'20220805' + verdict['glwu_ver'] = f'20220805' + verdict['gsi_ver'] = f'20240208' + verdict['lut_ver'] = f'20220805' + verdict['mom6_ver'] = f'20240416' + verdict['orog_ver'] = f'20231027' + verdict['reg2grb2_ver'] = f'20220805' + verdict['sfc_climo_ver'] = f'20220805' + verdict['ugwd_ver'] = f'20240624' + verdict['verif_ver'] = f'20220805' + verdict['wave_ver'] = f'20240105' + + gwhome = None + + opts, args = getopt.getopt(sys.argv[1:], '', ['help', 'atmgrid=', 'ocngrid=', + 'verbose=', 'localdir=', + 'gwhome=', + 'aer_ver=', + 'am_ver=', + 'chem_ver=', + 'cice_ver=', + 'cpl_ver=', + 'datm_ver=', + 'glwu_ver=', + 'gsi_ver=', + 'lut_ver=', + 'mom6_ver=', + 'orog_ver=', + 'reg2grb2_ver=', + 'sfc_climo_ver=', + 'ugwd_ver=', + 'verif_ver=', + 'wave_ver=']) for o, a in opts: # print(f'o: {o}, a: {a}') if o in ['--help']: print_usage(verdict) sys.exit(0) elif o in ['--verbose']: - verbose=int(a) + verbose = int(a) elif o in ['--atmgrid']: - atmgrid=a + atmgrid = a elif o in ['--ocngrid']: - ocngrid=a + ocngrid = a elif o in ['--localdir']: - localdir=a + localdir = a elif o in ['--gwhome']: - gwhome=a + gwhome = a else: - _, vername=o.split('--') + _, vername = o.split('--') print(f'vername: <{vername}>') - verdict[vername]=a + verdict[vername] = a if (atmgrid.find(',') > 0): - atmgridarray=atmgrid.split(',') + atmgridarray = atmgrid.split(',') else: - atmgridarray=[atmgrid] + atmgridarray = [atmgrid] for grid in atmgridarray: if (grid not in atmgridlist): @@ -320,9 +323,9 @@ def print_usage(verdict): sys.exit(-1) if (ocngrid.find(',') > 0): - ocngridarray=ocngrid.split(',') + ocngridarray = ocngrid.split(',') else: - ocngridarray=[ocngrid] + ocngridarray = [ocngrid] for grid in ocngridarray: if (grid not in ocngridlist): @@ -332,9 +335,9 @@ def print_usage(verdict): sys.exit(-1) # ------------------------------------------------------------------ - ffd=FetchFIXdata(atmgridarray=atmgridarray, - ocngridarray=ocngridarray, - localdir=localdir, verbose=verbose) + ffd = FetchFIXdata(atmgridarray=atmgridarray, + ocngridarray=ocngridarray, + localdir=localdir, verbose=verbose) if (gwhome is None): ffd.set_default_fix_ver(verdict) From c248e128c38079e09c9a54fcf5e69aad1036ec3a Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Thu, 27 Feb 2025 00:30:10 +0000 Subject: [PATCH 11/44] fix pynorm error 9 --- ush/fetch-fix-data.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ush/fetch-fix-data.py b/ush/fetch-fix-data.py index 97a649443bb..f75c80c9b06 100644 --- a/ush/fetch-fix-data.py +++ b/ush/fetch-fix-data.py @@ -11,8 +11,8 @@ from pathlib import Path # ------------------------------------------------------------------------------ -class FetchFIXdata(): +class FetchFIXdata(): def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], localdir=None, verbose=0): @@ -224,8 +224,8 @@ def set_default_fix_ver(self, verdict): self.fix_ver_dict = verdict # ----------------------------------------------------------------------------- -def print_usage(verdict): +def print_usage(verdict): print('Usage: python fetch-fix-data.py \\') print(' --atmgrid=AtmospericGrid (for multiple grids, separate with ",") \\') @@ -239,8 +239,8 @@ def print_usage(verdict): print(f'\t--{key}=yyyymmdd default: {verdict[key]}') # ------------------------------------------------------------------------------ -if __name__ == '__main__': +if __name__ == '__main__': atmgridlist = ['C48', 'C96', 'C192', 'C384', 'C768', 'C1152'] ocngridlist = ['500', '100', '050', '025'] From 85120f3398662440b804996c63695567247bbea9 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Thu, 27 Feb 2025 00:37:53 +0000 Subject: [PATCH 12/44] fix pynorm error 10 --- ush/fetch-fix-data.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ush/fetch-fix-data.py b/ush/fetch-fix-data.py index f75c80c9b06..e920723455f 100644 --- a/ush/fetch-fix-data.py +++ b/ush/fetch-fix-data.py @@ -12,6 +12,7 @@ # ------------------------------------------------------------------------------ + class FetchFIXdata(): def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], localdir=None, verbose=0): @@ -225,6 +226,7 @@ def set_default_fix_ver(self, verdict): # ----------------------------------------------------------------------------- + def print_usage(verdict): print('Usage: python fetch-fix-data.py \\') @@ -240,6 +242,7 @@ def print_usage(verdict): # ------------------------------------------------------------------------------ + if __name__ == '__main__': atmgridlist = ['C48', 'C96', 'C192', 'C384', 'C768', 'C1152'] From 2a7f1c9c103807fe8eef56741536286812bf15fd Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Thu, 27 Feb 2025 21:17:36 +0000 Subject: [PATCH 13/44] fix a syntax error --- ci/Jenkinsfile4AWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index c23ace3a968..731215a5665 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -6,7 +6,7 @@ def CI_CASES = '' def GH = 'none' // Location of the custom workspaces for each machine in the CI system. They are persistent for each iteration of the PR. def NodeName = [hera: 'Hera-EMC', orion: 'Orion-EMC', hercules: 'Hercules-EMC', gaea: 'Gaea', noaacloud: 'awsepicglobalworkflow'] -def custom_workspace = [hera: '/scratch1/NCEPDEV/global/CI', orion: '/work2/noaa/stmp/CI/ORION', hercules: '/work2/noaa/global/CI/HERCULES', gaea: '/gpfs/f5/epic/proj-shared/global/CI', noaacloud: /lustre/jenkins/global-workflow/CI] +def custom_workspace = [hera: '/scratch1/NCEPDEV/global/CI', orion: '/work2/noaa/stmp/CI/ORION', hercules: '/work2/noaa/global/CI/HERCULES', gaea: '/gpfs/f5/epic/proj-shared/global/CI', noaacloud: '/lustre/jenkins/global-workflow/CI'] def repo_url = 'git@github.com:NOAA-EMC/global-workflow.git' def STATUS = 'Passed' From 9f8ee2dd690e24c5d565ff08fb64c09b886cf4b8 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Thu, 27 Feb 2025 21:21:02 +0000 Subject: [PATCH 14/44] use just /lutre/jenkins for CI testing work directory --- ci/Jenkinsfile4AWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index 731215a5665..5efc18bf89f 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -6,7 +6,7 @@ def CI_CASES = '' def GH = 'none' // Location of the custom workspaces for each machine in the CI system. They are persistent for each iteration of the PR. def NodeName = [hera: 'Hera-EMC', orion: 'Orion-EMC', hercules: 'Hercules-EMC', gaea: 'Gaea', noaacloud: 'awsepicglobalworkflow'] -def custom_workspace = [hera: '/scratch1/NCEPDEV/global/CI', orion: '/work2/noaa/stmp/CI/ORION', hercules: '/work2/noaa/global/CI/HERCULES', gaea: '/gpfs/f5/epic/proj-shared/global/CI', noaacloud: '/lustre/jenkins/global-workflow/CI'] +def custom_workspace = [hera: '/scratch1/NCEPDEV/global/CI', orion: '/work2/noaa/stmp/CI/ORION', hercules: '/work2/noaa/global/CI/HERCULES', gaea: '/gpfs/f5/epic/proj-shared/global/CI', noaacloud: '/lustre/jenkins'] def repo_url = 'git@github.com:NOAA-EMC/global-workflow.git' def STATUS = 'Passed' From df4179cf441278ed14ef20061c5a5a0e2edac6a7 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Mon, 3 Mar 2025 16:01:03 +0000 Subject: [PATCH 15/44] using argparse and logging instead of getopt and print --- ush/fetch-fix-data.py | 209 +++++++++++++++++++----------------------- 1 file changed, 96 insertions(+), 113 deletions(-) diff --git a/ush/fetch-fix-data.py b/ush/fetch-fix-data.py index e920723455f..9d35e158774 100644 --- a/ush/fetch-fix-data.py +++ b/ush/fetch-fix-data.py @@ -7,17 +7,32 @@ import time import sys import getopt +import argparse import subprocess from pathlib import Path +import logging + +# Create and configure logger +logging.basicConfig(filename="cfetch-fix-data.log", + format='%(asctime)s %(message)s', + filemode='w') + +# Creating an object +logger = logging.getLogger() + +# Setting the threshold of logger to DEBUG +logger.setLevel(logging.DEBUG) # ------------------------------------------------------------------------------ class FetchFIXdata(): - def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], localdir=None, verbose=0): + def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], + fix_bucket=None, localdir=None, verbose=0): - self.aws_fix_bucket = f's3://noaa-nws-global-pds/fix' + # self.aws_fix_bucket = f's3://noaa-nws-global-pds/fix' + self.aws_fix_bucket = fix_bucket self.aws_cp = f'aws --no-sign-request s3 cp' self.aws_sync = f'aws --no-sign-request s3 sync' @@ -26,11 +41,11 @@ def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], localdir=None, ve self.localdir = localdir self.verbose = verbose - # if (os.path.isdir(localdir)): - # print('Prepare to download FIX data for %s and %s to %s' %(atmgrid, ocngrid, localdir)) - # else: - # print(f'local dir: <{localdir}> does not exist. Stop') - # sys.exit(-1) + if (os.path.isdir(localdir)): + logger.info(f'Prepare to download FIX data for {atmgrid} and {ocngrid} to {localdir}') + else: + logger.info(f'local dir: <{localdir}> does not exist. Stop') + sys.exit(-1) self.verdict = {} self.s3dict = {} @@ -125,20 +140,20 @@ def add_cpl2s3dict(self, varname, key, val): # ------------------------------------------------------------------------- def printinfo(self): - print(f'Preparing to fetch') - print(f'ATM grid: {self.atmgridarray}') - print(f'ONC grid: {self.ocngridarray}') - print(f'From: {self.aws_fix_bucket}') - print(f'To: {self.targetdir}') + logger.info(f'Preparing to fetch') + logger.info(f'ATM grid: {self.atmgridarray}') + logger.info(f'ONC grid: {self.ocngridarray}') + logger.info(f'From: {self.aws_fix_bucket}') + logger.info(f'To: {self.targetdir}') for key in self.s3dict.keys(): val = self.s3dict[key] - print(f'{key}: {val}') + logger.info(f'{key}: {val}') # ------------------------------------------------------------------------- def fetchdata(self): if (self.verbose): - print(f'Create local fix dir: {self.targetdir}') + logger.info(f'Create local fix dir: {self.targetdir}') path = Path(self.targetdir) path.mkdir(parents=True, exist_ok=True) @@ -160,28 +175,29 @@ def fetch_dir(self, dir): def download_dir(self, cmd, localdir): # returned_value = os.system(cmd) # returns the exit code in unix - # print('returned value:', returned_value) + # logger.info('returned value:', returned_value) if (os.path.isdir(localdir)): - print(f'{localdir} already exist. skip') + logger.info(f'{localdir} already exist. skip') else: parentdir, dirname = os.path.split(localdir) if (self.verbose): - print(f'Create local {parentdir} dir:') + logger.info(f'Create local {parentdir} dir:') path = Path(parentdir) path.mkdir(parents=True, exist_ok=True) if (self.verbose): - print(cmd) - print(f'Downloading {localdir}') + logger.info(cmd) + logger.info(f'Downloading {localdir}') returned_value = subprocess.call(cmd, shell=True) # returns the exit code in unix if (self.verbose): - print('returned value:', returned_value) + logger.info('returned value:', returned_value) # -------------------------------------------------------------------------- def fetch_ugwp_limb_tau(self): - ugwp_limb_tau_remotepath = f'{self.aws_fix_bucket}/ugwd/{self.fix_ver_dict['ugwd_ver']}/ugwp_limb_tau.nc' - ugwp_limb_tau_localdir = f'{self.targetdir}/ugwd/{self.fix_ver_dict['ugwd_ver']}' + ugwd_ver = self.fix_ver_dict['ugwd_ver'] + ugwp_limb_tau_remotepath = f'{self.aws_fix_bucket}/ugwd/{ugwd_ver}/ugwp_limb_tau.nc' + ugwp_limb_tau_localdir = f'{self.targetdir}/ugwd/{ugwd_ver}' filename = f'{ugwp_limb_tau_localdir}/ugwp_limb_tau.nc' path = Path(ugwp_limb_tau_localdir) path.mkdir(parents=True, exist_ok=True) @@ -192,17 +208,17 @@ def fetch_ugwp_limb_tau(self): def download_file(self, cmd, filename): # returned_value = os.system(cmd) # returns the exit code in unix - # print('returned value:', returned_value) + # logger.info('returned value:', returned_value) if (os.path.isfile(filename)): - print(f'{filename} already exist. skip') + logger.info(f'{filename} already exist. skip') else: if (self.verbose): - print(cmd) - print(f'Downloading {filename}') + logger.info(cmd) + logger.info(f'Downloading {filename}') returned_value = subprocess.call(cmd, shell=True) # returns the exit code in unix if (self.verbose): - print('returned value:', returned_value) + logger.info('returned value:', returned_value) # -------------------------------------------------------------------------- def set_fix_ver_from_gwhome(self, gwhome, verdict): @@ -217,7 +233,7 @@ def set_fix_ver_from_gwhome(self, gwhome, verdict): exphead, _, key = headstr.partition(' ') self.fix_ver_dict[key] = value else: - print(f'fix_ver_file: {ix_ver_file}s does not exist.') + logger.info(f'fix_ver_file: {fix_ver_file}s does not exist.') # ------------------------------------------------------------------------ def set_default_fix_ver(self, verdict): @@ -227,18 +243,11 @@ def set_default_fix_ver(self, verdict): # ----------------------------------------------------------------------------- -def print_usage(verdict): - - print('Usage: python fetch-fix-data.py \\') - print(' --atmgrid=AtmospericGrid (for multiple grids, separate with ",") \\') - print(' --ocngrid=OceanGrid (for multiple grids, separate with ",") \\') - print(' --localdir=Your-local-fix-dir \\') - print(' [options]') - print('options are:') - print('\t--gwhome=xxxx (Global-Workflow directory)') - - for key in verdict.keys(): - print(f'\t--{key}=yyyymmdd default: {verdict[key]}') +def namespace_to_dict(namespace): + return { + k: namespace_to_dict(v) if isinstance(v, argparse.Namespace) else v + for k, v in vars(namespace).items() + } # ------------------------------------------------------------------------------ @@ -248,71 +257,43 @@ def print_usage(verdict): atmgridlist = ['C48', 'C96', 'C192', 'C384', 'C768', 'C1152'] ocngridlist = ['500', '100', '050', '025'] - verbose = 0 - atmgrid = f'C48' - ocngrid = f'500' - localdir = f'/contrib/global-workflow-shared-data' - - # default fix-version - verdict = {} - verdict['aer_ver'] = f'20220805' - verdict['am_ver'] = f'20220805' - verdict['chem_ver'] = f'20220805' - verdict['cice_ver'] = f'20240416' - verdict['cpl_ver'] = f'20230526' - verdict['datm_ver'] = f'20220805' - verdict['glwu_ver'] = f'20220805' - verdict['gsi_ver'] = f'20240208' - verdict['lut_ver'] = f'20220805' - verdict['mom6_ver'] = f'20240416' - verdict['orog_ver'] = f'20231027' - verdict['reg2grb2_ver'] = f'20220805' - verdict['sfc_climo_ver'] = f'20220805' - verdict['ugwd_ver'] = f'20240624' - verdict['verif_ver'] = f'20220805' - verdict['wave_ver'] = f'20240105' - - gwhome = None - - opts, args = getopt.getopt(sys.argv[1:], '', ['help', 'atmgrid=', 'ocngrid=', - 'verbose=', 'localdir=', - 'gwhome=', - 'aer_ver=', - 'am_ver=', - 'chem_ver=', - 'cice_ver=', - 'cpl_ver=', - 'datm_ver=', - 'glwu_ver=', - 'gsi_ver=', - 'lut_ver=', - 'mom6_ver=', - 'orog_ver=', - 'reg2grb2_ver=', - 'sfc_climo_ver=', - 'ugwd_ver=', - 'verif_ver=', - 'wave_ver=']) - for o, a in opts: - # print(f'o: {o}, a: {a}') - if o in ['--help']: - print_usage(verdict) - sys.exit(0) - elif o in ['--verbose']: - verbose = int(a) - elif o in ['--atmgrid']: - atmgrid = a - elif o in ['--ocngrid']: - ocngrid = a - elif o in ['--localdir']: - localdir = a - elif o in ['--gwhome']: - gwhome = a - else: - _, vername = o.split('--') - print(f'vername: <{vername}>') - verdict[vername] = a + parser = argparse.ArgumentParser() + parser.add_argument("-v", "--verbose", action="store_true", + help="increase output verbosity") + parser.add_argument("-a", "--atmgrid", type=str, required=True, + help="ATM grid, like: C48, C96, C192, C384, C768, C1152") + parser.add_argument("-o", "--ocngrid", type=str, required=True, + help="OCN grid, like: 500, 100, 050, 025") + parser.add_argument("--localdir", type=str, required=True, + help="local directory to store FIX data subset") + parser.add_argument("--gwhome", type=str, default='unknown', + help="GW home diretory where can find fix.ver") + parser.add_argument("--fix_bucket", type=str, default='s3://noaa-nws-global-pds/fix', + help="S3 Bucket directory of FIX data") + parser.add_argument("--aer_ver", type=str, default='20220805', help="AER version") + parser.add_argument("--am_ver", type=str, default='20220805', help="AM version") + parser.add_argument("--chem_ver", type=str, default='20220805', help="chem version") + parser.add_argument("--cice_ver", type=str, default='20240416', help="cice version") + parser.add_argument("--cpl_ver", type=str, default='20230526', help="cpl version") + parser.add_argument("--datm_ver", type=str, default='20220805', help="datm version") + parser.add_argument("--glwu_ver", type=str, default='20220805', help="glwu version") + parser.add_argument("--gsi_ver", type=str, default='20240208', help="gsi version") + parser.add_argument("--lut_ver", type=str, default='20220805', help="lut version") + parser.add_argument("--mom6_ver", type=str, default='20240416', help="mom6 version") + parser.add_argument("--orog_ver", type=str, default='20231027', help="orog version") + parser.add_argument("--reg2grb2_ver", type=str, default='20220805', help="reg2grb2 version") + parser.add_argument("--sfc_climo_ver", type=str, default='20220805', help="sfc_climo version") + parser.add_argument("--ugwd_ver", type=str, default='20220805', help="ugwd version") + parser.add_argument("--verif_ver", type=str, default='20220805', help="verif version") + parser.add_argument("--wave_ver", type=str, default='20220805', help="wave version") + args = parser.parse_args() + + if args.verbose: + logger.info(f"the atmgrid is {args.atmgrid}") + else: + logger.info(f"the atmgrid is {args.atmgrid}") + atmgrid = args.atmgrid if (atmgrid.find(',') > 0): atmgridarray = atmgrid.split(',') else: @@ -320,11 +301,11 @@ def print_usage(verdict): for grid in atmgridarray: if (grid not in atmgridlist): - print('atmgrid: ', grid) - print('is not in supported grids: ', atmgridlist) - print_usage(verdict) + logger.info(f'atmgrid: {grid}') + logger.info(f'is not in supported grids: {atmgridlist}') sys.exit(-1) + ocngrid = args.ocngrid if (ocngrid.find(',') > 0): ocngridarray = ocngrid.split(',') else: @@ -332,20 +313,22 @@ def print_usage(verdict): for grid in ocngridarray: if (grid not in ocngridlist): - print('ocngrid: ', grid) - print('is not in supported grids: ', ocngridlist) - print_usage(verdict) + logger.info(f'ocngrid: {grid}') + logger.info(f'is not in supported grids: {ocngridlist}') sys.exit(-1) + verdict = namespace_to_dict(args) + # ------------------------------------------------------------------ ffd = FetchFIXdata(atmgridarray=atmgridarray, ocngridarray=ocngridarray, - localdir=localdir, verbose=verbose) + fix_bucket=args.fix_bucket, + localdir=args.localdir, verbose=args.verbose) - if (gwhome is None): + if (args.gwhome is None): ffd.set_default_fix_ver(verdict) else: - ffd.set_fix_ver_from_gwhome(gwhome, verdict) + ffd.set_fix_ver_from_gwhome(args.gwhome, verdict) ffd.update_s3dict() ffd.fetchdata() From 6a168ae2de2a6c566b88dcf67000b8747e1d8b88 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Mon, 3 Mar 2025 16:08:10 +0000 Subject: [PATCH 16/44] using argparse and logging instead of getopt and print --- ush/fetch-fix-data.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ush/fetch-fix-data.py b/ush/fetch-fix-data.py index 9d35e158774..aa71f7e4f96 100644 --- a/ush/fetch-fix-data.py +++ b/ush/fetch-fix-data.py @@ -42,10 +42,10 @@ def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], self.verbose = verbose if (os.path.isdir(localdir)): - logger.info(f'Prepare to download FIX data for {atmgrid} and {ocngrid} to {localdir}') + logger.info(f'Prepare to download FIX data for {atmgrid} and {ocngrid} to {localdir}') else: - logger.info(f'local dir: <{localdir}> does not exist. Stop') - sys.exit(-1) + logger.info(f'local dir: <{localdir}> does not exist. Stop') + sys.exit(-1) self.verdict = {} self.s3dict = {} From a23662f56c9e4e825c2d85347a5577e719d9ef10 Mon Sep 17 00:00:00 2001 From: Kris Booker Date: Mon, 3 Mar 2025 09:50:50 -0700 Subject: [PATCH 17/44] Updating with proper nomenclature. --- ci/Jenkinsfile4AWS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index 5efc18bf89f..2e5be62544b 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -5,9 +5,9 @@ def HOMEgfs = 'none' def CI_CASES = '' def GH = 'none' // Location of the custom workspaces for each machine in the CI system. They are persistent for each iteration of the PR. -def NodeName = [hera: 'Hera-EMC', orion: 'Orion-EMC', hercules: 'Hercules-EMC', gaea: 'Gaea', noaacloud: 'awsepicglobalworkflow'] -def custom_workspace = [hera: '/scratch1/NCEPDEV/global/CI', orion: '/work2/noaa/stmp/CI/ORION', hercules: '/work2/noaa/global/CI/HERCULES', gaea: '/gpfs/f5/epic/proj-shared/global/CI', noaacloud: '/lustre/jenkins'] -def repo_url = 'git@github.com:NOAA-EMC/global-workflow.git' +def NodeName = [hera: 'Hera-EMC', orion: 'Orion-EMC', hercules: 'Hercules-EMC', gaea: 'Gaea', Awsepicglobalworkflow: 'awsepicglobalworkflow'] +def custom_workspace = [hera: '/scratch1/NCEPDEV/global/CI', orion: '/work2/noaa/stmp/CI/ORION', hercules: '/work2/noaa/global/CI/HERCULES', gaea: '/gpfs/f5/epic/proj-shared/global/CI', Awsepicglobalworkflow: '/lustre/jenkins'] +def repo_url = 'git@github.com:NOAA-EPIC/global-workflow-cloud.git' def STATUS = 'Passed' pipeline { From 6b60421e3690fae483df646160fa5a774e031891 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Mon, 3 Mar 2025 18:27:59 +0000 Subject: [PATCH 18/44] consist with Terry's code --- ci/Jenkinsfile4AWS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index 2e5be62544b..a162b578072 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -5,8 +5,8 @@ def HOMEgfs = 'none' def CI_CASES = '' def GH = 'none' // Location of the custom workspaces for each machine in the CI system. They are persistent for each iteration of the PR. -def NodeName = [hera: 'Hera-EMC', orion: 'Orion-EMC', hercules: 'Hercules-EMC', gaea: 'Gaea', Awsepicglobalworkflow: 'awsepicglobalworkflow'] -def custom_workspace = [hera: '/scratch1/NCEPDEV/global/CI', orion: '/work2/noaa/stmp/CI/ORION', hercules: '/work2/noaa/global/CI/HERCULES', gaea: '/gpfs/f5/epic/proj-shared/global/CI', Awsepicglobalworkflow: '/lustre/jenkins'] +def NodeName = [hera: 'Hera-EMC', orion: 'Orion-EMC', hercules: 'Hercules-EMC', gaea: 'Gaea', awsepicglobalworkflow: 'Awsepicglobalworkflow'] +def custom_workspace = [hera: '/scratch1/NCEPDEV/global/CI', orion: '/work2/noaa/stmp/CI/ORION', hercules: '/work2/noaa/global/CI/HERCULES', gaea: '/gpfs/f5/epic/proj-shared/global/CI', awsepicglobalworkflow: '/lustre/jenkins'] def repo_url = 'git@github.com:NOAA-EPIC/global-workflow-cloud.git' def STATUS = 'Passed' @@ -79,7 +79,7 @@ pipeline { Machine = machine[0].toUpperCase() + machine.substring(1) echo "Getting Common Workspace for ${Machine}" ws("${custom_workspace[machine]}/${env.CHANGE_ID}") { - properties([parameters([[$class: 'NodeParameterDefinition', allowedSlaves: ['built-in', 'Hercules-EMC', 'Hera-EMC', 'Orion-EMC', 'Gaea', 'awsepicglobalworkflow'], defaultSlaves: ['built-in'], name: '', nodeEligibility: [$class: 'AllNodeEligibility'], triggerIfResult: 'allCases']])]) + properties([parameters([[$class: 'NodeParameterDefinition', allowedSlaves: ['built-in', 'Hercules-EMC', 'Hera-EMC', 'Orion-EMC', 'Gaea', 'Awsepicglobalworkflow'], defaultSlaves: ['built-in'], name: '', nodeEligibility: [$class: 'AllNodeEligibility'], triggerIfResult: 'allCases']])]) GH = sh(script: "which gh || echo '~/bin/gh'", returnStdout: true).trim() CUSTOM_WORKSPACE = "${WORKSPACE}" HOMEgfs = "${CUSTOM_WORKSPACE}/global-workflow" From 35f35f2496983bbd817c779907b0a3beff8c315c Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Mon, 3 Mar 2025 21:40:43 +0000 Subject: [PATCH 19/44] add a ls command to make sure code in cloned --- ci/Jenkinsfile4AWS | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index a162b578072..449bffc20b4 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -120,6 +120,7 @@ pipeline { def error_logs_message = "" dir("${HOMEgfs}/sorc") { try { + sh(script: 'ls *.sh') // list files here to make sure all files exist. sh(script: './build_compute.sh all') // build the global-workflow executables } catch (Exception error_build) { echo "Failed to build global-workflow: ${error_build.getMessage()}" From 9e53aa44cc4227cca767b759adb0129824766920 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Mon, 3 Mar 2025 23:10:41 +0000 Subject: [PATCH 20/44] try clone the code directly --- ci/Jenkinsfile4AWS | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index 449bffc20b4..b1ca85ee876 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -100,12 +100,14 @@ pipeline { ws(HOMEgfs) { echo "Checking out the code on ${Machine} using scm in ${HOMEgfs}" try { - checkout scm + // checkout scm + sh(script: "git clone --recursive ${repo_url}") } catch (Exception e) { echo "Failed to checkout the code on ${Machine} using scm in ${HOMEgfs}, try again ..." sleep time: 45, unit: 'SECONDS' try { - checkout scm + // checkout scm + sh(script: "git clone --recursive ${repo_url}") } catch (Exception ee) { echo "Failed to checkout the code on ${Machine} using scm in ${HOMEgfs}: ${ee.getMessage()}" if (env.CHANGE_ID) { @@ -121,6 +123,7 @@ pipeline { dir("${HOMEgfs}/sorc") { try { sh(script: 'ls *.sh') // list files here to make sure all files exist. + sh(script: 'ls ./build_compute.sh') // list files here to make sure all files exist. sh(script: './build_compute.sh all') // build the global-workflow executables } catch (Exception error_build) { echo "Failed to build global-workflow: ${error_build.getMessage()}" From 98c50d9a46342a9fac3a68a830e4256559de745f Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Mon, 3 Mar 2025 23:57:51 +0000 Subject: [PATCH 21/44] use https to clone --- ci/Jenkinsfile4AWS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index b1ca85ee876..016857f62fb 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -7,7 +7,8 @@ def GH = 'none' // Location of the custom workspaces for each machine in the CI system. They are persistent for each iteration of the PR. def NodeName = [hera: 'Hera-EMC', orion: 'Orion-EMC', hercules: 'Hercules-EMC', gaea: 'Gaea', awsepicglobalworkflow: 'Awsepicglobalworkflow'] def custom_workspace = [hera: '/scratch1/NCEPDEV/global/CI', orion: '/work2/noaa/stmp/CI/ORION', hercules: '/work2/noaa/global/CI/HERCULES', gaea: '/gpfs/f5/epic/proj-shared/global/CI', awsepicglobalworkflow: '/lustre/jenkins'] -def repo_url = 'git@github.com:NOAA-EPIC/global-workflow-cloud.git' +// def repo_url = 'git@github.com:NOAA-EPIC/global-workflow-cloud.git' +def repo_url = 'https://github.com/NOAA-EPIC/global-workflow-cloud.git' def STATUS = 'Passed' pipeline { From 3089f00f23bb4bfa0f8c96b768c06255c746e9ff Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Tue, 4 Mar 2025 16:09:55 +0000 Subject: [PATCH 22/44] add more debug ls --- ci/Jenkinsfile4AWS | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index 016857f62fb..a13a3e38b92 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -4,11 +4,14 @@ def CUSTOM_WORKSPACE = 'none' def HOMEgfs = 'none' def CI_CASES = '' def GH = 'none' +//Trivial change // Location of the custom workspaces for each machine in the CI system. They are persistent for each iteration of the PR. def NodeName = [hera: 'Hera-EMC', orion: 'Orion-EMC', hercules: 'Hercules-EMC', gaea: 'Gaea', awsepicglobalworkflow: 'Awsepicglobalworkflow'] def custom_workspace = [hera: '/scratch1/NCEPDEV/global/CI', orion: '/work2/noaa/stmp/CI/ORION', hercules: '/work2/noaa/global/CI/HERCULES', gaea: '/gpfs/f5/epic/proj-shared/global/CI', awsepicglobalworkflow: '/lustre/jenkins'] // def repo_url = 'git@github.com:NOAA-EPIC/global-workflow-cloud.git' def repo_url = 'https://github.com/NOAA-EPIC/global-workflow-cloud.git' +// def aws_gw_name = 'global-workflow" +def aws_gw_name = 'global-workflow-cloud" def STATUS = 'Passed' pipeline { @@ -45,7 +48,9 @@ pipeline { for (label in pullRequest.labels) { if (label.matches("CI-(.*?)-Ready")) { def machine_name = label.split('-')[1].toString().toLowerCase() + print machine_name jenkins.model.Jenkins.get().computers.each { c -> + print c.node.selfLabel.name if (c.node.selfLabel.name == NodeName[machine_name]) { run_nodes.add(c.node.selfLabel.name) } @@ -57,7 +62,7 @@ pipeline { run_nodes.init().each { node -> def machine_name = node.split('-')[0].toLowerCase() echo "Spawning job on node: ${node} with machine name: ${machine_name}" - build job: "/global-workflow/EMC-Global-Pipeline/PR-${env.CHANGE_ID}", parameters: [ + build job: "/${aws_gw_name}/EPIC-AWS-CI-Pipeline/PR-${env.CHANGE_ID}", parameters: [ string(name: 'machine', value: machine_name), string(name: 'Node', value: node) ], wait: false @@ -83,8 +88,8 @@ pipeline { properties([parameters([[$class: 'NodeParameterDefinition', allowedSlaves: ['built-in', 'Hercules-EMC', 'Hera-EMC', 'Orion-EMC', 'Gaea', 'Awsepicglobalworkflow'], defaultSlaves: ['built-in'], name: '', nodeEligibility: [$class: 'AllNodeEligibility'], triggerIfResult: 'allCases']])]) GH = sh(script: "which gh || echo '~/bin/gh'", returnStdout: true).trim() CUSTOM_WORKSPACE = "${WORKSPACE}" - HOMEgfs = "${CUSTOM_WORKSPACE}/global-workflow" - sh(script: "rm -Rf ${CUSTOM_WORKSPACE}/global-workflow; mkdir -p ${CUSTOM_WORKSPACE}/global-workflow") + HOMEgfs = "${CUSTOM_WORKSPACE}/${aws_gw_name}" + sh(script: "rm -Rf ${CUSTOM_WORKSPACE}/${aws_gw_name}; mkdir -p ${CUSTOM_WORKSPACE}/${aws_gw_name}") sh(script: "rm -Rf ${CUSTOM_WORKSPACE}/RUNTESTS; mkdir -p ${CUSTOM_WORKSPACE}/RUNTESTS") sh(script: """${GH} pr edit ${env.CHANGE_ID} --repo ${repo_url} --add-label "CI-${Machine}-Building" --remove-label "CI-${Machine}-Ready" """) } @@ -103,12 +108,14 @@ pipeline { try { // checkout scm sh(script: "git clone --recursive ${repo_url}") + sh(script: "ls ${HOMEgfs}") } catch (Exception e) { echo "Failed to checkout the code on ${Machine} using scm in ${HOMEgfs}, try again ..." sleep time: 45, unit: 'SECONDS' try { // checkout scm sh(script: "git clone --recursive ${repo_url}") + sh(script: "ls ${HOMEgfs}") } catch (Exception ee) { echo "Failed to checkout the code on ${Machine} using scm in ${HOMEgfs}: ${ee.getMessage()}" if (env.CHANGE_ID) { From 57b2a519dd168ab914795dd6bb48e62b9300e64b Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Tue, 4 Mar 2025 20:23:52 +0000 Subject: [PATCH 23/44] fix a typo --- ci/Jenkinsfile4AWS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index a13a3e38b92..6a0ad2e23c8 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -10,8 +10,8 @@ def NodeName = [hera: 'Hera-EMC', orion: 'Orion-EMC', hercules: 'Hercules-EMC', def custom_workspace = [hera: '/scratch1/NCEPDEV/global/CI', orion: '/work2/noaa/stmp/CI/ORION', hercules: '/work2/noaa/global/CI/HERCULES', gaea: '/gpfs/f5/epic/proj-shared/global/CI', awsepicglobalworkflow: '/lustre/jenkins'] // def repo_url = 'git@github.com:NOAA-EPIC/global-workflow-cloud.git' def repo_url = 'https://github.com/NOAA-EPIC/global-workflow-cloud.git' -// def aws_gw_name = 'global-workflow" -def aws_gw_name = 'global-workflow-cloud" +// def aws_gw_name = 'global-workflow' +def aws_gw_name = 'global-workflow-cloud' def STATUS = 'Passed' pipeline { From 8fefe2a2873e411730fd9baacf5b3094dd01e746 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Tue, 4 Mar 2025 20:49:55 +0000 Subject: [PATCH 24/44] remove 2 comments --- ci/Jenkinsfile4AWS | 2 -- 1 file changed, 2 deletions(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index 6a0ad2e23c8..7f65aed9d8b 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -8,9 +8,7 @@ def GH = 'none' // Location of the custom workspaces for each machine in the CI system. They are persistent for each iteration of the PR. def NodeName = [hera: 'Hera-EMC', orion: 'Orion-EMC', hercules: 'Hercules-EMC', gaea: 'Gaea', awsepicglobalworkflow: 'Awsepicglobalworkflow'] def custom_workspace = [hera: '/scratch1/NCEPDEV/global/CI', orion: '/work2/noaa/stmp/CI/ORION', hercules: '/work2/noaa/global/CI/HERCULES', gaea: '/gpfs/f5/epic/proj-shared/global/CI', awsepicglobalworkflow: '/lustre/jenkins'] -// def repo_url = 'git@github.com:NOAA-EPIC/global-workflow-cloud.git' def repo_url = 'https://github.com/NOAA-EPIC/global-workflow-cloud.git' -// def aws_gw_name = 'global-workflow' def aws_gw_name = 'global-workflow-cloud' def STATUS = 'Passed' From 8f6db95c5df3235ddc6fbb40fbca896ad46190b4 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Tue, 4 Mar 2025 21:35:37 +0000 Subject: [PATCH 25/44] reset HOMEgfs --- ci/Jenkinsfile4AWS | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index 7f65aed9d8b..bd5554d1768 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -126,6 +126,7 @@ pipeline { def gist_url = "" def error_logs = "" def error_logs_message = "" + HOMEgfs = "${CUSTOM_WORKSPACE}/${aws_gw_name}/${aws_gw_name}" dir("${HOMEgfs}/sorc") { try { sh(script: 'ls *.sh') // list files here to make sure all files exist. From 1f05a51c0753e7ae3080d6e784fa3adde8f3c1eb Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Tue, 4 Mar 2025 22:03:21 +0000 Subject: [PATCH 26/44] compile for gfs only for now --- ci/Jenkinsfile4AWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index bd5554d1768..98efcde33c7 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -131,7 +131,7 @@ pipeline { try { sh(script: 'ls *.sh') // list files here to make sure all files exist. sh(script: 'ls ./build_compute.sh') // list files here to make sure all files exist. - sh(script: './build_compute.sh all') // build the global-workflow executables + sh(script: './build_compute.sh gfs') // build the global-workflow executables } catch (Exception error_build) { echo "Failed to build global-workflow: ${error_build.getMessage()}" if ( fileExists("logs/error.logs") ) { From 4640b6a5143b6717e8bc5b7a403cdc6643a549d0 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Wed, 5 Mar 2025 00:04:50 +0000 Subject: [PATCH 27/44] comment gh pr eidt for now --- ci/Jenkinsfile4AWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index 98efcde33c7..4722068f157 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -89,7 +89,7 @@ pipeline { HOMEgfs = "${CUSTOM_WORKSPACE}/${aws_gw_name}" sh(script: "rm -Rf ${CUSTOM_WORKSPACE}/${aws_gw_name}; mkdir -p ${CUSTOM_WORKSPACE}/${aws_gw_name}") sh(script: "rm -Rf ${CUSTOM_WORKSPACE}/RUNTESTS; mkdir -p ${CUSTOM_WORKSPACE}/RUNTESTS") - sh(script: """${GH} pr edit ${env.CHANGE_ID} --repo ${repo_url} --add-label "CI-${Machine}-Building" --remove-label "CI-${Machine}-Ready" """) + // sh(script: """${GH} pr edit ${env.CHANGE_ID} --repo ${repo_url} --add-label "CI-${Machine}-Building" --remove-label "CI-${Machine}-Ready" """) } echo "Building and running on ${Machine} in directory ${CUSTOM_WORKSPACE}" } From c906547c62a7020f9b7a00285b71359222d63781 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Wed, 5 Mar 2025 01:41:14 +0000 Subject: [PATCH 28/44] skip CI on AWS --- ci/cases/pr/C48_S2SW_extended.yaml | 1 + ci/cases/pr/C48mx500_3DVarAOWCDA.yaml | 1 + ci/cases/pr/C48mx500_hybAOWCDA.yaml | 1 + ci/cases/pr/C96C48_hybatmDA.yaml | 3 +++ ci/cases/pr/C96C48_hybatmaerosnowDA.yaml | 1 + ci/cases/pr/C96C48_ufs_hybatmDA.yaml | 1 + ci/cases/pr/C96_atm3DVar.yaml | 1 + ci/cases/pr/C96_atm3DVar_extended.yaml | 1 + ci/cases/pr/C96mx100_S2S.yaml | 1 + 9 files changed, 11 insertions(+) diff --git a/ci/cases/pr/C48_S2SW_extended.yaml b/ci/cases/pr/C48_S2SW_extended.yaml index 11e0af9cb94..06d3ffff4c0 100644 --- a/ci/cases/pr/C48_S2SW_extended.yaml +++ b/ci/cases/pr/C48_S2SW_extended.yaml @@ -19,4 +19,5 @@ skip_ci_on_hosts: - gaeac6 - orion - hercules + - awsepicglobalworkflow - wcoss2 # TODO run on WCOSS2 once the gfs_waveawipsbulls job is fixed diff --git a/ci/cases/pr/C48mx500_3DVarAOWCDA.yaml b/ci/cases/pr/C48mx500_3DVarAOWCDA.yaml index fcfb3caadc6..f3627b4c1a1 100644 --- a/ci/cases/pr/C48mx500_3DVarAOWCDA.yaml +++ b/ci/cases/pr/C48mx500_3DVarAOWCDA.yaml @@ -21,3 +21,4 @@ skip_ci_on_hosts: - gaeac6 - gaeac5 - orion + - awsepicglobalworkflow diff --git a/ci/cases/pr/C48mx500_hybAOWCDA.yaml b/ci/cases/pr/C48mx500_hybAOWCDA.yaml index 36ea62b2dfd..1d9a5c526b8 100644 --- a/ci/cases/pr/C48mx500_hybAOWCDA.yaml +++ b/ci/cases/pr/C48mx500_hybAOWCDA.yaml @@ -22,3 +22,4 @@ skip_ci_on_hosts: - gaeac5 - gaeac6 - orion + - awsepicglobalworkflow diff --git a/ci/cases/pr/C96C48_hybatmDA.yaml b/ci/cases/pr/C96C48_hybatmDA.yaml index c0833acf141..abb6c1b0c55 100644 --- a/ci/cases/pr/C96C48_hybatmDA.yaml +++ b/ci/cases/pr/C96C48_hybatmDA.yaml @@ -17,3 +17,6 @@ arguments: interval: 24 start: cold yaml: {{ HOMEgfs }}/ci/cases/yamls/gfs_defaults_ci.yaml + +skip_ci_on_hosts: + - awsepicglobalworkflow diff --git a/ci/cases/pr/C96C48_hybatmaerosnowDA.yaml b/ci/cases/pr/C96C48_hybatmaerosnowDA.yaml index e231f30b047..78106beb3e3 100644 --- a/ci/cases/pr/C96C48_hybatmaerosnowDA.yaml +++ b/ci/cases/pr/C96C48_hybatmaerosnowDA.yaml @@ -22,3 +22,4 @@ skip_ci_on_hosts: - gaeac5 - gaeac6 - hercules + - awsepicglobalworkflow diff --git a/ci/cases/pr/C96C48_ufs_hybatmDA.yaml b/ci/cases/pr/C96C48_ufs_hybatmDA.yaml index 18fe4168c4e..74f31a27940 100644 --- a/ci/cases/pr/C96C48_ufs_hybatmDA.yaml +++ b/ci/cases/pr/C96C48_ufs_hybatmDA.yaml @@ -22,3 +22,4 @@ skip_ci_on_hosts: - gaeac6 - orion - hercules + - awsepicglobalworkflow diff --git a/ci/cases/pr/C96_atm3DVar.yaml b/ci/cases/pr/C96_atm3DVar.yaml index 0b242fbfd38..74490f69aaa 100644 --- a/ci/cases/pr/C96_atm3DVar.yaml +++ b/ci/cases/pr/C96_atm3DVar.yaml @@ -18,3 +18,4 @@ arguments: skip_ci_on_hosts: - wcoss2 + - awsepicglobalworkflow diff --git a/ci/cases/pr/C96_atm3DVar_extended.yaml b/ci/cases/pr/C96_atm3DVar_extended.yaml index a76c87b5fad..27a839f076f 100644 --- a/ci/cases/pr/C96_atm3DVar_extended.yaml +++ b/ci/cases/pr/C96_atm3DVar_extended.yaml @@ -22,3 +22,4 @@ skip_ci_on_hosts: - gaeac6 - orion - hercules + - awsepicglobalworkflow diff --git a/ci/cases/pr/C96mx100_S2S.yaml b/ci/cases/pr/C96mx100_S2S.yaml index 0f61c48fe62..4ce7c5e206d 100644 --- a/ci/cases/pr/C96mx100_S2S.yaml +++ b/ci/cases/pr/C96mx100_S2S.yaml @@ -20,3 +20,4 @@ arguments: skip_ci_on_hosts: - gaeac6 - gaeac5 + - awsepicglobalworkflow From eac272e7ce4d4023cb3f3895e03dc8d692581761 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Wed, 5 Mar 2025 16:03:56 +0000 Subject: [PATCH 29/44] trying to fix runtime bug --- ci/Jenkinsfile4AWS | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index 4722068f157..9c60020ef32 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -85,7 +85,7 @@ pipeline { ws("${custom_workspace[machine]}/${env.CHANGE_ID}") { properties([parameters([[$class: 'NodeParameterDefinition', allowedSlaves: ['built-in', 'Hercules-EMC', 'Hera-EMC', 'Orion-EMC', 'Gaea', 'Awsepicglobalworkflow'], defaultSlaves: ['built-in'], name: '', nodeEligibility: [$class: 'AllNodeEligibility'], triggerIfResult: 'allCases']])]) GH = sh(script: "which gh || echo '~/bin/gh'", returnStdout: true).trim() - CUSTOM_WORKSPACE = "${WORKSPACE}" + CUSTOM_WORKSPACE = "${WORKSPACE}/${aws_gw_name}" HOMEgfs = "${CUSTOM_WORKSPACE}/${aws_gw_name}" sh(script: "rm -Rf ${CUSTOM_WORKSPACE}/${aws_gw_name}; mkdir -p ${CUSTOM_WORKSPACE}/${aws_gw_name}") sh(script: "rm -Rf ${CUSTOM_WORKSPACE}/RUNTESTS; mkdir -p ${CUSTOM_WORKSPACE}/RUNTESTS") @@ -126,14 +126,13 @@ pipeline { def gist_url = "" def error_logs = "" def error_logs_message = "" - HOMEgfs = "${CUSTOM_WORKSPACE}/${aws_gw_name}/${aws_gw_name}" dir("${HOMEgfs}/sorc") { try { sh(script: 'ls *.sh') // list files here to make sure all files exist. sh(script: 'ls ./build_compute.sh') // list files here to make sure all files exist. - sh(script: './build_compute.sh gfs') // build the global-workflow executables + sh(script: './build_compute.sh gfs') // build the ${aws_gw_name} executables } catch (Exception error_build) { - echo "Failed to build global-workflow: ${error_build.getMessage()}" + echo "Failed to build ${aws_gw_name}: ${error_build.getMessage()}" if ( fileExists("logs/error.logs") ) { def fileContent = readFile 'logs/error.logs' def lines = fileContent.readLines() @@ -162,10 +161,10 @@ pipeline { echo "Failed to comment on PR: ${error_comment.getMessage()}" } STATUS = 'Failed' - error("Failed to build global-workflow on ${Machine}") + error("Failed to build ${aws_gw_name} on ${Machine}") } STATUS = 'Failed' - error("Failed to build global-workflow on ${Machine} and no error.logs file found") + error("Failed to build ${aws_gw_name} on ${Machine} and no error.logs file found") } sh(script: './link_workflow.sh') } @@ -201,6 +200,7 @@ pipeline { script { env.RUNTESTS = "${CUSTOM_WORKSPACE}/RUNTESTS" try { + echo "HOMEgfs: ${HOMEgfs}" error_output = sh(script: """ source ${HOMEgfs}/workflow/gw_setup.sh ${HOMEgfs}/ci/scripts/utils/ci_utils_wrapper.sh create_experiment ${HOMEgfs}/ci/cases/pr/${caseName}.yaml @@ -219,9 +219,10 @@ pipeline { def error_file = "${CUSTOM_WORKSPACE}/RUNTESTS/${pslot}_error.logs" sh(script: " rm -f ${error_file}") try { + echo "HOMEgfs: ${HOMEgfs}" sh(script: """ source ${HOMEgfs}/workflow/gw_setup.sh - ${HOMEgfs}/ci/scripts/run-check_ci.sh ${CUSTOM_WORKSPACE} ${pslot} 'global-workflow' + ${HOMEgfs}/ci/scripts/run-check_ci.sh ${CUSTOM_WORKSPACE} ${pslot} "${aws_gw_name}" """) sh(script: """ source ${HOMEgfs}/workflow/gw_setup.sh @@ -310,7 +311,7 @@ pipeline { echo "Failed to remove custom work directory ${CUSTOM_WORKSPACE} on ${Machine}: ${e.getMessage()}" } } else { - echo "Failed to build and run global-workflow in ${CUSTOM_WORKSPACE} on ${Machine}" + echo "Failed to build and run ${aws_gw_name} in ${CUSTOM_WORKSPACE} on ${Machine}" } } } From 35a6cd0ead24c2c7731ac9b734c2e037bf905951 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Wed, 5 Mar 2025 17:36:22 +0000 Subject: [PATCH 30/44] still trying to figure out HOEgfs issue --- ci/Jenkinsfile4AWS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index 9c60020ef32..054568f7d85 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -86,7 +86,7 @@ pipeline { properties([parameters([[$class: 'NodeParameterDefinition', allowedSlaves: ['built-in', 'Hercules-EMC', 'Hera-EMC', 'Orion-EMC', 'Gaea', 'Awsepicglobalworkflow'], defaultSlaves: ['built-in'], name: '', nodeEligibility: [$class: 'AllNodeEligibility'], triggerIfResult: 'allCases']])]) GH = sh(script: "which gh || echo '~/bin/gh'", returnStdout: true).trim() CUSTOM_WORKSPACE = "${WORKSPACE}/${aws_gw_name}" - HOMEgfs = "${CUSTOM_WORKSPACE}/${aws_gw_name}" + HOMEgfs = "${CUSTOM_WORKSPACE}" sh(script: "rm -Rf ${CUSTOM_WORKSPACE}/${aws_gw_name}; mkdir -p ${CUSTOM_WORKSPACE}/${aws_gw_name}") sh(script: "rm -Rf ${CUSTOM_WORKSPACE}/RUNTESTS; mkdir -p ${CUSTOM_WORKSPACE}/RUNTESTS") // sh(script: """${GH} pr edit ${env.CHANGE_ID} --repo ${repo_url} --add-label "CI-${Machine}-Building" --remove-label "CI-${Machine}-Ready" """) @@ -126,6 +126,7 @@ pipeline { def gist_url = "" def error_logs = "" def error_logs_message = "" + HOMEgfs = "${CUSTOM_WORKSPACE}/${aws_gw_name}" dir("${HOMEgfs}/sorc") { try { sh(script: 'ls *.sh') // list files here to make sure all files exist. From b55f4a17ef14ce0974be023e8bbdfb1a50274df8 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Wed, 5 Mar 2025 21:00:51 +0000 Subject: [PATCH 31/44] add compile gefs --- ci/Jenkinsfile4AWS | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index 054568f7d85..8f6f15db934 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -89,7 +89,7 @@ pipeline { HOMEgfs = "${CUSTOM_WORKSPACE}" sh(script: "rm -Rf ${CUSTOM_WORKSPACE}/${aws_gw_name}; mkdir -p ${CUSTOM_WORKSPACE}/${aws_gw_name}") sh(script: "rm -Rf ${CUSTOM_WORKSPACE}/RUNTESTS; mkdir -p ${CUSTOM_WORKSPACE}/RUNTESTS") - // sh(script: """${GH} pr edit ${env.CHANGE_ID} --repo ${repo_url} --add-label "CI-${Machine}-Building" --remove-label "CI-${Machine}-Ready" """) + sh(script: """${GH} pr edit ${env.CHANGE_ID} --repo ${repo_url} --add-label "CI-${Machine}-Building" --remove-label "CI-${Machine}-Ready" """) } echo "Building and running on ${Machine} in directory ${CUSTOM_WORKSPACE}" } @@ -104,15 +104,15 @@ pipeline { ws(HOMEgfs) { echo "Checking out the code on ${Machine} using scm in ${HOMEgfs}" try { - // checkout scm - sh(script: "git clone --recursive ${repo_url}") + checkout scm + // sh(script: "git clone --recursive ${repo_url}") sh(script: "ls ${HOMEgfs}") } catch (Exception e) { echo "Failed to checkout the code on ${Machine} using scm in ${HOMEgfs}, try again ..." sleep time: 45, unit: 'SECONDS' try { - // checkout scm - sh(script: "git clone --recursive ${repo_url}") + checkout scm + // sh(script: "git clone --recursive ${repo_url}") sh(script: "ls ${HOMEgfs}") } catch (Exception ee) { echo "Failed to checkout the code on ${Machine} using scm in ${HOMEgfs}: ${ee.getMessage()}" @@ -132,6 +132,7 @@ pipeline { sh(script: 'ls *.sh') // list files here to make sure all files exist. sh(script: 'ls ./build_compute.sh') // list files here to make sure all files exist. sh(script: './build_compute.sh gfs') // build the ${aws_gw_name} executables + sh(script: './build_compute.sh gefs') // build the ${aws_gw_name} executables } catch (Exception error_build) { echo "Failed to build ${aws_gw_name}: ${error_build.getMessage()}" if ( fileExists("logs/error.logs") ) { From e1724cb02fdde8419dccef48788ea0826ea04576 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Wed, 5 Mar 2025 21:57:54 +0000 Subject: [PATCH 32/44] add compile gefs --- ci/Jenkinsfile4AWS | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index 8f6f15db934..fdc6dfd0eee 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -85,6 +85,7 @@ pipeline { ws("${custom_workspace[machine]}/${env.CHANGE_ID}") { properties([parameters([[$class: 'NodeParameterDefinition', allowedSlaves: ['built-in', 'Hercules-EMC', 'Hera-EMC', 'Orion-EMC', 'Gaea', 'Awsepicglobalworkflow'], defaultSlaves: ['built-in'], name: '', nodeEligibility: [$class: 'AllNodeEligibility'], triggerIfResult: 'allCases']])]) GH = sh(script: "which gh || echo '~/bin/gh'", returnStdout: true).trim() + echo "GH: ${GH}" CUSTOM_WORKSPACE = "${WORKSPACE}/${aws_gw_name}" HOMEgfs = "${CUSTOM_WORKSPACE}" sh(script: "rm -Rf ${CUSTOM_WORKSPACE}/${aws_gw_name}; mkdir -p ${CUSTOM_WORKSPACE}/${aws_gw_name}") From 4264c15c82f36ec75fe318d19856c94f318819bc Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Wed, 5 Mar 2025 22:27:28 +0000 Subject: [PATCH 33/44] add compile gefs --- ci/Jenkinsfile4AWS | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index fdc6dfd0eee..b0528436a1e 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -90,7 +90,7 @@ pipeline { HOMEgfs = "${CUSTOM_WORKSPACE}" sh(script: "rm -Rf ${CUSTOM_WORKSPACE}/${aws_gw_name}; mkdir -p ${CUSTOM_WORKSPACE}/${aws_gw_name}") sh(script: "rm -Rf ${CUSTOM_WORKSPACE}/RUNTESTS; mkdir -p ${CUSTOM_WORKSPACE}/RUNTESTS") - sh(script: """${GH} pr edit ${env.CHANGE_ID} --repo ${repo_url} --add-label "CI-${Machine}-Building" --remove-label "CI-${Machine}-Ready" """) + // sh(script: """${GH} pr edit ${env.CHANGE_ID} --repo ${repo_url} --add-label "CI-${Machine}-Building" --remove-label "CI-${Machine}-Ready" """) } echo "Building and running on ${Machine} in directory ${CUSTOM_WORKSPACE}" } @@ -105,15 +105,15 @@ pipeline { ws(HOMEgfs) { echo "Checking out the code on ${Machine} using scm in ${HOMEgfs}" try { - checkout scm - // sh(script: "git clone --recursive ${repo_url}") + // checkout scm + sh(script: "git clone --recursive ${repo_url}") sh(script: "ls ${HOMEgfs}") } catch (Exception e) { echo "Failed to checkout the code on ${Machine} using scm in ${HOMEgfs}, try again ..." sleep time: 45, unit: 'SECONDS' try { - checkout scm - // sh(script: "git clone --recursive ${repo_url}") + // checkout scm + sh(script: "git clone --recursive ${repo_url}") sh(script: "ls ${HOMEgfs}") } catch (Exception ee) { echo "Failed to checkout the code on ${Machine} using scm in ${HOMEgfs}: ${ee.getMessage()}" From 20c1211a530efb8c3ed9fcba56eb0210b4171797 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Tue, 11 Mar 2025 21:22:07 +0000 Subject: [PATCH 34/44] switch back to 'checkout scm instead of git clone' --- ci/Jenkinsfile4AWS | 10 +++++----- ci/cases/pr/C48_S2SW.yaml | 3 +++ ci/scripts/utils/ci_utils.sh | 13 +++++++++++-- ci/scripts/utils/launch_java_agent.sh | 9 ++++++++- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index b0528436a1e..fdc6dfd0eee 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -90,7 +90,7 @@ pipeline { HOMEgfs = "${CUSTOM_WORKSPACE}" sh(script: "rm -Rf ${CUSTOM_WORKSPACE}/${aws_gw_name}; mkdir -p ${CUSTOM_WORKSPACE}/${aws_gw_name}") sh(script: "rm -Rf ${CUSTOM_WORKSPACE}/RUNTESTS; mkdir -p ${CUSTOM_WORKSPACE}/RUNTESTS") - // sh(script: """${GH} pr edit ${env.CHANGE_ID} --repo ${repo_url} --add-label "CI-${Machine}-Building" --remove-label "CI-${Machine}-Ready" """) + sh(script: """${GH} pr edit ${env.CHANGE_ID} --repo ${repo_url} --add-label "CI-${Machine}-Building" --remove-label "CI-${Machine}-Ready" """) } echo "Building and running on ${Machine} in directory ${CUSTOM_WORKSPACE}" } @@ -105,15 +105,15 @@ pipeline { ws(HOMEgfs) { echo "Checking out the code on ${Machine} using scm in ${HOMEgfs}" try { - // checkout scm - sh(script: "git clone --recursive ${repo_url}") + checkout scm + // sh(script: "git clone --recursive ${repo_url}") sh(script: "ls ${HOMEgfs}") } catch (Exception e) { echo "Failed to checkout the code on ${Machine} using scm in ${HOMEgfs}, try again ..." sleep time: 45, unit: 'SECONDS' try { - // checkout scm - sh(script: "git clone --recursive ${repo_url}") + checkout scm + // sh(script: "git clone --recursive ${repo_url}") sh(script: "ls ${HOMEgfs}") } catch (Exception ee) { echo "Failed to checkout the code on ${Machine} using scm in ${HOMEgfs}: ${ee.getMessage()}" diff --git a/ci/cases/pr/C48_S2SW.yaml b/ci/cases/pr/C48_S2SW.yaml index 63675645148..5ca9d45d4f4 100644 --- a/ci/cases/pr/C48_S2SW.yaml +++ b/ci/cases/pr/C48_S2SW.yaml @@ -12,3 +12,6 @@ arguments: idate: 2021032312 edate: 2021032312 yaml: {{ HOMEgfs }}/ci/cases/yamls/gfs_defaults_ci.yaml + +skip_ci_on_hosts: + - awsepicglobalworkflow diff --git a/ci/scripts/utils/ci_utils.sh b/ci/scripts/utils/ci_utils.sh index 56b0571adca..085b4c54fa7 100755 --- a/ci/scripts/utils/ci_utils.sh +++ b/ci/scripts/utils/ci_utils.sh @@ -119,11 +119,20 @@ function create_experiment () { case=$(basename "${yaml_config}" .yaml) || true export pslot=${case}_${pr_sha} - source "${HOMEgfs}/ci/platforms/config.${MACHINE_ID}" + if [[ ${MACHINE_ID} == "noaacloud" ]]; then + source "${HOMEgfs}/ci/platforms/config.${PW_CSP}" + else + source "${HOMEgfs}/ci/platforms/config.${MACHINE_ID}" + fi + source "${HOMEgfs}/workflow/gw_setup.sh" # Remove RUNDIRS dir incase this is a retry (STMP now in host file) - STMP=$("${HOMEgfs}/ci/scripts/utils/parse_yaml.py" -y "${HOMEgfs}/workflow/hosts/${MACHINE_ID}.yaml" -k STMP -s) + if [[ ${MACHINE_ID} == "noaacloud" ]]; then + STMP=$("${HOMEgfs}/ci/scripts/utils/parse_yaml.py" -y "${HOMEgfs}/workflow/hosts/${PW_CSP}pw.yaml" -k STMP -s) + else + STMP=$("${HOMEgfs}/ci/scripts/utils/parse_yaml.py" -y "${HOMEgfs}/workflow/hosts/${MACHINE_ID}.yaml" -k STMP -s) + fi echo "Removing ${STMP}/RUNDIRS/${pslot} directory incase this is a retry" rm -Rf "${STMP}/RUNDIRS/${pslot}" diff --git a/ci/scripts/utils/launch_java_agent.sh b/ci/scripts/utils/launch_java_agent.sh index 539ba4ca99d..8854f794152 100755 --- a/ci/scripts/utils/launch_java_agent.sh +++ b/ci/scripts/utils/launch_java_agent.sh @@ -76,6 +76,8 @@ source "${HOMEGFS_}/ush/detect_machine.sh" case ${MACHINE_ID} in hera | orion | hercules | wcoss2 | gaeac5 | gaeac6 ) echo "Launch Jenkins Java Controler on ${MACHINE_ID}";; + noaacloud ) + echo "Launch Jenkins Java Controler on ${PW_CSP}";; *) echo "Unsupported platform. Exiting with error." exit 1;; @@ -87,7 +89,12 @@ rm -f "${LOG}" HOMEgfs="${HOMEGFS_}" source "${HOMEGFS_}/ush/module-setup.sh" module use "${HOMEGFS_}/modulefiles" module load "module_gwsetup.${MACHINE_ID}" -source "${HOMEGFS_}/ci/platforms/config.${MACHINE_ID}" + +if [[ ${MACHINE_ID} == "noaacloud" ]]; then + source "${HOMEgfs_}/ci/platforms/config.${PW_CSP}" +else + source "${HOMEgfs_}/ci/platforms/config.${MACHINE_ID}" +fi JAVA_HOME="${JENKINS_AGENT_LANUCH_DIR}/JAVA/jdk-17.0.10" if [[ ! -d "${JAVA_HOME}" ]]; then From f8a6a6d8c0ebc66a23254210b1ce7130048f37ca Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Wed, 12 Mar 2025 14:46:48 +0000 Subject: [PATCH 35/44] using checkout scm --- ci/Jenkinsfile4AWS | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index fdc6dfd0eee..80d2a99e691 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -8,7 +8,8 @@ def GH = 'none' // Location of the custom workspaces for each machine in the CI system. They are persistent for each iteration of the PR. def NodeName = [hera: 'Hera-EMC', orion: 'Orion-EMC', hercules: 'Hercules-EMC', gaea: 'Gaea', awsepicglobalworkflow: 'Awsepicglobalworkflow'] def custom_workspace = [hera: '/scratch1/NCEPDEV/global/CI', orion: '/work2/noaa/stmp/CI/ORION', hercules: '/work2/noaa/global/CI/HERCULES', gaea: '/gpfs/f5/epic/proj-shared/global/CI', awsepicglobalworkflow: '/lustre/jenkins'] -def repo_url = 'https://github.com/NOAA-EPIC/global-workflow-cloud.git' +// def repo_url = 'https://github.com/NOAA-EPIC/global-workflow-cloud.git' +def repo_url = 'git@github.com:NOAA-EMC/global-workflow.git' def aws_gw_name = 'global-workflow-cloud' def STATUS = 'Passed' @@ -105,16 +106,18 @@ pipeline { ws(HOMEgfs) { echo "Checking out the code on ${Machine} using scm in ${HOMEgfs}" try { + echo "Check out code with scm" checkout scm // sh(script: "git clone --recursive ${repo_url}") - sh(script: "ls ${HOMEgfs}") + // sh(script: "ls ${HOMEgfs}") } catch (Exception e) { echo "Failed to checkout the code on ${Machine} using scm in ${HOMEgfs}, try again ..." sleep time: 45, unit: 'SECONDS' try { + echo "Check out code with scm" checkout scm // sh(script: "git clone --recursive ${repo_url}") - sh(script: "ls ${HOMEgfs}") + // sh(script: "ls ${HOMEgfs}") } catch (Exception ee) { echo "Failed to checkout the code on ${Machine} using scm in ${HOMEgfs}: ${ee.getMessage()}" if (env.CHANGE_ID) { From c952a7300eb708197669fa82155912a6fc208af9 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Wed, 12 Mar 2025 14:48:11 +0000 Subject: [PATCH 36/44] using checkout scm --- ci/Jenkinsfile4AWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index 80d2a99e691..cc24c2cb5b1 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -9,7 +9,7 @@ def GH = 'none' def NodeName = [hera: 'Hera-EMC', orion: 'Orion-EMC', hercules: 'Hercules-EMC', gaea: 'Gaea', awsepicglobalworkflow: 'Awsepicglobalworkflow'] def custom_workspace = [hera: '/scratch1/NCEPDEV/global/CI', orion: '/work2/noaa/stmp/CI/ORION', hercules: '/work2/noaa/global/CI/HERCULES', gaea: '/gpfs/f5/epic/proj-shared/global/CI', awsepicglobalworkflow: '/lustre/jenkins'] // def repo_url = 'https://github.com/NOAA-EPIC/global-workflow-cloud.git' -def repo_url = 'git@github.com:NOAA-EMC/global-workflow.git' +def repo_url = 'git@github.com:NOAA-EPIC/global-workflow-cloud.git' def aws_gw_name = 'global-workflow-cloud' def STATUS = 'Passed' From 12b09df40fbafd9dae146b2fe6116dd6e0964c49 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Thu, 13 Mar 2025 00:14:36 +0000 Subject: [PATCH 37/44] remove memory from resource if on AWS --- parm/config/gfs/config.resources.AWSPW | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/parm/config/gfs/config.resources.AWSPW b/parm/config/gfs/config.resources.AWSPW index d044c475fb3..85a7293b06c 100644 --- a/parm/config/gfs/config.resources.AWSPW +++ b/parm/config/gfs/config.resources.AWSPW @@ -4,13 +4,7 @@ export is_exclusive="True" unset memory - -# shellcheck disable=SC2312 -for mem_var in $(env | grep '^memory_' | cut -d= -f1); do - unset "${mem_var}" -done - -step=$1 +unset "memory_${RUN}" case ${step} in "fcst" | "efcs") From 98570b7f6e0c4473781bbd78ebcef384812ac57d Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Thu, 13 Mar 2025 19:16:33 +0000 Subject: [PATCH 38/44] remove memory requirement for AWS --- ci/Jenkinsfile4AWS | 72 ++++++++++++++++++-------- parm/config/gfs/config.resources.AWSPW | 6 +++ 2 files changed, 55 insertions(+), 23 deletions(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index cc24c2cb5b1..64f8a54077b 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -8,8 +8,7 @@ def GH = 'none' // Location of the custom workspaces for each machine in the CI system. They are persistent for each iteration of the PR. def NodeName = [hera: 'Hera-EMC', orion: 'Orion-EMC', hercules: 'Hercules-EMC', gaea: 'Gaea', awsepicglobalworkflow: 'Awsepicglobalworkflow'] def custom_workspace = [hera: '/scratch1/NCEPDEV/global/CI', orion: '/work2/noaa/stmp/CI/ORION', hercules: '/work2/noaa/global/CI/HERCULES', gaea: '/gpfs/f5/epic/proj-shared/global/CI', awsepicglobalworkflow: '/lustre/jenkins'] -// def repo_url = 'https://github.com/NOAA-EPIC/global-workflow-cloud.git' -def repo_url = 'git@github.com:NOAA-EPIC/global-workflow-cloud.git' +def repo_url = 'https://github.com/NOAA-EPIC/global-workflow-cloud.git' def aws_gw_name = 'global-workflow-cloud' def STATUS = 'Passed' @@ -83,12 +82,13 @@ pipeline { script { Machine = machine[0].toUpperCase() + machine.substring(1) echo "Getting Common Workspace for ${Machine}" + echo "Common Workspace for ${Machine} is ${custom_workspace[machine]}/${env.CHANGE_ID}" + echo "WORKSPACE: {WORKSPACE}" ws("${custom_workspace[machine]}/${env.CHANGE_ID}") { properties([parameters([[$class: 'NodeParameterDefinition', allowedSlaves: ['built-in', 'Hercules-EMC', 'Hera-EMC', 'Orion-EMC', 'Gaea', 'Awsepicglobalworkflow'], defaultSlaves: ['built-in'], name: '', nodeEligibility: [$class: 'AllNodeEligibility'], triggerIfResult: 'allCases']])]) GH = sh(script: "which gh || echo '~/bin/gh'", returnStdout: true).trim() - echo "GH: ${GH}" - CUSTOM_WORKSPACE = "${WORKSPACE}/${aws_gw_name}" - HOMEgfs = "${CUSTOM_WORKSPACE}" + CUSTOM_WORKSPACE = "${WORKSPACE}" + HOMEgfs = "${CUSTOM_WORKSPACE}/${aws_gw_name}" sh(script: "rm -Rf ${CUSTOM_WORKSPACE}/${aws_gw_name}; mkdir -p ${CUSTOM_WORKSPACE}/${aws_gw_name}") sh(script: "rm -Rf ${CUSTOM_WORKSPACE}/RUNTESTS; mkdir -p ${CUSTOM_WORKSPACE}/RUNTESTS") sh(script: """${GH} pr edit ${env.CHANGE_ID} --repo ${repo_url} --add-label "CI-${Machine}-Building" --remove-label "CI-${Machine}-Ready" """) @@ -106,18 +106,47 @@ pipeline { ws(HOMEgfs) { echo "Checking out the code on ${Machine} using scm in ${HOMEgfs}" try { - echo "Check out code with scm" - checkout scm - // sh(script: "git clone --recursive ${repo_url}") - // sh(script: "ls ${HOMEgfs}") + echo "Getting Common Workspace for ${Machine}" + echo "Common Workspace for ${Machine} is ${custom_workspace[machine]}/${env.CHANGE_ID}" + echo "WORKSPACE: {WORKSPACE}" + echo "CUSTOM_WORKSPACE: {CUSTOM_WORKSPACE}" + + checkout([$class: 'GitSCM', + branches: [[name: "develop"]], + doGenerateSubmoduleConfigurations: false, + extensions: [[$class: 'SubmoduleOption', + disableSubmodules: false, + parentCredentials: false, + recursiveSubmodules: true, + reference: '', + trackingSubmodules: false], + [$class: 'CleanBeforeCheckout'], + [$class: 'CleanCheckout']], + submoduleCfg: [], + userRemoteConfigs: [[url: ${repo_url}]]]) + //sh(script: "git clone --recursive ${repo_url}") + sh(script: "pwd") + sh(script: "ls ${HOMEgfs}") } catch (Exception e) { echo "Failed to checkout the code on ${Machine} using scm in ${HOMEgfs}, try again ..." sleep time: 45, unit: 'SECONDS' try { - echo "Check out code with scm" - checkout scm - // sh(script: "git clone --recursive ${repo_url}") - // sh(script: "ls ${HOMEgfs}") + // checkout scm + checkout([$class: 'GitSCM', + branches: [[name: "develop"]], + doGenerateSubmoduleConfigurations: false, + extensions: [[$class: 'SubmoduleOption', + disableSubmodules: false, + parentCredentials: false, + recursiveSubmodules: true, + reference: '', + trackingSubmodules: false], + [$class: 'CleanBeforeCheckout'], + [$class: 'CleanCheckout']], + submoduleCfg: [], + userRemoteConfigs: [[url: ${repo_url}]]]) + //sh(script: "git clone --recursive ${repo_url}") + sh(script: "ls ${HOMEgfs}") } catch (Exception ee) { echo "Failed to checkout the code on ${Machine} using scm in ${HOMEgfs}: ${ee.getMessage()}" if (env.CHANGE_ID) { @@ -130,15 +159,14 @@ pipeline { def gist_url = "" def error_logs = "" def error_logs_message = "" - HOMEgfs = "${CUSTOM_WORKSPACE}/${aws_gw_name}" + HOMEgfs = "${CUSTOM_WORKSPACE}/${aws_gw_name}/${aws_gw_name}" dir("${HOMEgfs}/sorc") { try { sh(script: 'ls *.sh') // list files here to make sure all files exist. sh(script: 'ls ./build_compute.sh') // list files here to make sure all files exist. - sh(script: './build_compute.sh gfs') // build the ${aws_gw_name} executables - sh(script: './build_compute.sh gefs') // build the ${aws_gw_name} executables + sh(script: './build_compute.sh gfs') // build the global-workflow executables } catch (Exception error_build) { - echo "Failed to build ${aws_gw_name}: ${error_build.getMessage()}" + echo "Failed to build global-workflow: ${error_build.getMessage()}" if ( fileExists("logs/error.logs") ) { def fileContent = readFile 'logs/error.logs' def lines = fileContent.readLines() @@ -167,10 +195,10 @@ pipeline { echo "Failed to comment on PR: ${error_comment.getMessage()}" } STATUS = 'Failed' - error("Failed to build ${aws_gw_name} on ${Machine}") + error("Failed to build global-workflow on ${Machine}") } STATUS = 'Failed' - error("Failed to build ${aws_gw_name} on ${Machine} and no error.logs file found") + error("Failed to build global-workflow on ${Machine} and no error.logs file found") } sh(script: './link_workflow.sh') } @@ -206,7 +234,6 @@ pipeline { script { env.RUNTESTS = "${CUSTOM_WORKSPACE}/RUNTESTS" try { - echo "HOMEgfs: ${HOMEgfs}" error_output = sh(script: """ source ${HOMEgfs}/workflow/gw_setup.sh ${HOMEgfs}/ci/scripts/utils/ci_utils_wrapper.sh create_experiment ${HOMEgfs}/ci/cases/pr/${caseName}.yaml @@ -225,10 +252,9 @@ pipeline { def error_file = "${CUSTOM_WORKSPACE}/RUNTESTS/${pslot}_error.logs" sh(script: " rm -f ${error_file}") try { - echo "HOMEgfs: ${HOMEgfs}" sh(script: """ source ${HOMEgfs}/workflow/gw_setup.sh - ${HOMEgfs}/ci/scripts/run-check_ci.sh ${CUSTOM_WORKSPACE} ${pslot} "${aws_gw_name}" + ${HOMEgfs}/ci/scripts/run-check_ci.sh ${CUSTOM_WORKSPACE} ${pslot} 'global-workflow' """) sh(script: """ source ${HOMEgfs}/workflow/gw_setup.sh @@ -317,7 +343,7 @@ pipeline { echo "Failed to remove custom work directory ${CUSTOM_WORKSPACE} on ${Machine}: ${e.getMessage()}" } } else { - echo "Failed to build and run ${aws_gw_name} in ${CUSTOM_WORKSPACE} on ${Machine}" + echo "Failed to build and run global-workflow in ${CUSTOM_WORKSPACE} on ${Machine}" } } } diff --git a/parm/config/gfs/config.resources.AWSPW b/parm/config/gfs/config.resources.AWSPW index 85a7293b06c..0255a9adad3 100644 --- a/parm/config/gfs/config.resources.AWSPW +++ b/parm/config/gfs/config.resources.AWSPW @@ -18,6 +18,12 @@ case ${step} in ;; + "atmos_products" | "oceanice_products" | "wavepostsbs" ) + export PARTITION_BATCH="process" + max_tasks_per_node=24 + ;; + + *) export PARTITION_BATCH="process" max_tasks_per_node=24 From fd63bdb5051376f15cdc916194ec793a5a1afa4f Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Tue, 18 Mar 2025 21:12:27 +0000 Subject: [PATCH 39/44] fix a crontab shell issue, and make sure fcst use compute partition, and others use process partition --- parm/config/gefs/config.resources.AWSPW | 54 ++++--------------------- parm/config/gfs/config.resources.AWSPW | 22 ++++------ workflow/hosts/awspw.yaml | 1 + workflow/rocoto/tasks.py | 4 ++ workflow/rocoto/workflow_xml.py | 14 +++---- 5 files changed, 27 insertions(+), 68 deletions(-) diff --git a/parm/config/gefs/config.resources.AWSPW b/parm/config/gefs/config.resources.AWSPW index 43cfcf56cce..071c102e3af 100644 --- a/parm/config/gefs/config.resources.AWSPW +++ b/parm/config/gefs/config.resources.AWSPW @@ -4,66 +4,26 @@ export is_exclusive="True" unset memory - -# shellcheck disable=SC2312 -for mem_var in $(env | grep '^memory_' | cut -d= -f1); do - unset "${mem_var}" -done +unset "memory_${RUN}" step=$1 case ${step} in - "fcst" | "efcs") - export PARTITION_BATCH="compute" - max_tasks_per_node=48 - ;; - - "arch_vrfy" | "arch_tars") - export PARTITION_BATCH="process" - max_tasks_per_node=24 - ;; - - "prep_emissions") - export PARTITION_BATCH="process" - max_tasks_per_node=24 - export ntasks=1 - export threads_per_task=1 - export tasks_per_node=$(( max_tasks_per_node / threads_per_task )) - ;; - - "waveinit") - export PARTITION_BATCH="process" - max_tasks_per_node=24 - export ntasks=12 - export threads_per_task=1 - export tasks_per_node=$(( max_tasks_per_node / threads_per_task )) - export NTASKS=${ntasks} - ;; - - "wavepostpnt") + "fcst" | "efcs" | "wavepostbndpnt" | "wavepostpnt") export PARTITION_BATCH="compute" + unset PARTITION_SERVICE max_tasks_per_node=48 - export ntasks=240 - export threads_per_task=1 - export tasks_per_node=$(( max_tasks_per_node / threads_per_task )) - export NTASKS=${ntasks} - ;; - - "wavepostsbs" | "wavepostbndpnt" | "wavepostbndpntbll") - export PARTITION_BATCH="process" - max_tasks_per_node=24 - export ntasks=24 - export threads_per_task=1 - export tasks_per_node=$(( max_tasks_per_node / threads_per_task )) - export NTASKS=${ntasks} + tasks_per_node=48 ;; *) export PARTITION_BATCH="process" + unset PARTITION_SERVICE max_tasks_per_node=24 + tasks_per_node=24 ;; esac export max_tasks_per_node - +export tasks_per_node diff --git a/parm/config/gfs/config.resources.AWSPW b/parm/config/gfs/config.resources.AWSPW index 0255a9adad3..071c102e3af 100644 --- a/parm/config/gfs/config.resources.AWSPW +++ b/parm/config/gfs/config.resources.AWSPW @@ -6,30 +6,24 @@ export is_exclusive="True" unset memory unset "memory_${RUN}" +step=$1 + case ${step} in - "fcst" | "efcs") + "fcst" | "efcs" | "wavepostbndpnt" | "wavepostpnt") export PARTITION_BATCH="compute" + unset PARTITION_SERVICE max_tasks_per_node=48 + tasks_per_node=48 ;; - "arch_vrfy" | "arch_tars") - export PARTITION_BATCH="process" - max_tasks_per_node=24 - ;; - - - "atmos_products" | "oceanice_products" | "wavepostsbs" ) - export PARTITION_BATCH="process" - max_tasks_per_node=24 - ;; - - *) export PARTITION_BATCH="process" + unset PARTITION_SERVICE max_tasks_per_node=24 + tasks_per_node=24 ;; esac export max_tasks_per_node - +export tasks_per_node diff --git a/workflow/hosts/awspw.yaml b/workflow/hosts/awspw.yaml index 0c54b95f725..6976e2e46bc 100644 --- a/workflow/hosts/awspw.yaml +++ b/workflow/hosts/awspw.yaml @@ -10,6 +10,7 @@ ACCOUNT: '${USER}' SCHEDULER: slurm QUEUE: batch PARTITION_BATCH: compute +PARTITION_SERVICE: process CHGRP_RSTPROD: 'YES' CHGRP_CMD: 'chgrp rstprod' # TODO: This is not yet supported. HPSS_PROJECT: emc-global #TODO: See `ATARDIR` below. diff --git a/workflow/rocoto/tasks.py b/workflow/rocoto/tasks.py index ac5cc914a22..b9483808d90 100644 --- a/workflow/rocoto/tasks.py +++ b/workflow/rocoto/tasks.py @@ -405,6 +405,10 @@ def get_resource(self, task_name): else: # This is a batch task task_partition = self.partition_batch + # on CSPs, partition_batch for fcst/efcs/wavepostbndpnt is "compute", + # others are "process". So need to modify task_partition here. + if (task_config['PARTITION_BATCH'] != self.partition_batch): + task_partition =task_config['PARTITION_BATCH'] task_queue = self.queue_batch task_clusters = self.clusters_batch task_constraint = self.constraint_batch diff --git a/workflow/rocoto/workflow_xml.py b/workflow/rocoto/workflow_xml.py index e265a11904a..9b9ca306657 100644 --- a/workflow/rocoto/workflow_xml.py +++ b/workflow/rocoto/workflow_xml.py @@ -175,6 +175,13 @@ def _write_crontab(self, crontab_file: str = None, cronint: int = 5) -> None: f'#################### {self.pslot} ####################' ] + # AWS need 'SHELL', and 'BASH_ENV' defined, or, the crontab job won't start. + if os.environ.get('PW_CSP', None) in ['aws', 'azure', 'google']: + crontab_strings.extend([ + 'SHELL="/bin/bash"', + 'BASH_ENV="/etc/bashrc"' + ]) + # Construct the crontab or scrontab if self.use_scrontab: # The slurm crontab needs an SCRON entry that calls a script @@ -218,13 +225,6 @@ def _write_crontab(self, crontab_file: str = None, cronint: int = 5) -> None: '' ]) - # AWS need 'SHELL', and 'BASH_ENV' defined, or, the crontab job won't start. - if os.environ.get('PW_CSP', None) in ['aws', 'azure', 'google']: - crontab_strings.extend([ - 'SHELL="/bin/bash"', - 'BASH_ENV="/etc/bashrc"' - ]) - if crontab_file is None: crontab_file = f"{self.expdir}/{self.pslot}.crontab" From 17e90478fccabdfe1f48c9928627e21ee8c11679 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Tue, 18 Mar 2025 21:16:33 +0000 Subject: [PATCH 40/44] fix a pynorms error --- workflow/rocoto/tasks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflow/rocoto/tasks.py b/workflow/rocoto/tasks.py index b9483808d90..f67490268b6 100644 --- a/workflow/rocoto/tasks.py +++ b/workflow/rocoto/tasks.py @@ -408,7 +408,7 @@ def get_resource(self, task_name): # on CSPs, partition_batch for fcst/efcs/wavepostbndpnt is "compute", # others are "process". So need to modify task_partition here. if (task_config['PARTITION_BATCH'] != self.partition_batch): - task_partition =task_config['PARTITION_BATCH'] + task_partition = task_config['PARTITION_BATCH'] task_queue = self.queue_batch task_clusters = self.clusters_batch task_constraint = self.constraint_batch From b861bdab8945035c221ad99550850c944b3faa22 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Thu, 20 Mar 2025 14:36:25 +0000 Subject: [PATCH 41/44] remove a ls command, and combine compile to one command --- ci/Jenkinsfile4AWS | 4 +--- parm/config/gfs/config.resources.AWSPW | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index d17fce36e1b..c9872f90ca0 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -132,9 +132,7 @@ pipeline { def error_logs_message = "" dir("${HOMEgfs}/sorc") { try { - sh(script: 'ls ./build_compute.sh') // list files here to make sure all files exist. - sh(script: './build_compute.sh gfs') // build the global-workflow executables - sh(script: './build_compute.sh gefs') // build the global-workflow executables + sh(script: './build_compute.sh gfs gefs sfs') // build the global-workflow executables } catch (Exception error_build) { echo "Failed to build global-workflow: ${error_build.getMessage()}" if ( fileExists("logs/error.logs") ) { diff --git a/parm/config/gfs/config.resources.AWSPW b/parm/config/gfs/config.resources.AWSPW index 071c102e3af..17a3924d29c 100644 --- a/parm/config/gfs/config.resources.AWSPW +++ b/parm/config/gfs/config.resources.AWSPW @@ -9,7 +9,7 @@ unset "memory_${RUN}" step=$1 case ${step} in - "fcst" | "efcs" | "wavepostbndpnt" | "wavepostpnt") + "fcst" | "efcs" | "wavepostpnt") export PARTITION_BATCH="compute" unset PARTITION_SERVICE max_tasks_per_node=48 From a1a10d0249319449f7191e9854aa67074e30794c Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Thu, 20 Mar 2025 15:15:06 +0000 Subject: [PATCH 42/44] remove for this branch --- ush/fetch-fix-data.py | 334 ------------------------------------------ 1 file changed, 334 deletions(-) delete mode 100644 ush/fetch-fix-data.py diff --git a/ush/fetch-fix-data.py b/ush/fetch-fix-data.py deleted file mode 100644 index aa71f7e4f96..00000000000 --- a/ush/fetch-fix-data.py +++ /dev/null @@ -1,334 +0,0 @@ -#!/usr/bin/env python -# cfetch-fix-data.py -# wei.huang@noaa.gov -# 2025-02-26 -# script to download a subset of FIX data to local machines. -import os -import time -import sys -import getopt -import argparse -import subprocess -from pathlib import Path -import logging - -# Create and configure logger -logging.basicConfig(filename="cfetch-fix-data.log", - format='%(asctime)s %(message)s', - filemode='w') - -# Creating an object -logger = logging.getLogger() - -# Setting the threshold of logger to DEBUG -logger.setLevel(logging.DEBUG) - -# ------------------------------------------------------------------------------ - - -class FetchFIXdata(): - - def __init__(self, atmgridarray=['C48'], ocngridarray=['500'], - fix_bucket=None, localdir=None, verbose=0): - - # self.aws_fix_bucket = f's3://noaa-nws-global-pds/fix' - self.aws_fix_bucket = fix_bucket - self.aws_cp = f'aws --no-sign-request s3 cp' - self.aws_sync = f'aws --no-sign-request s3 sync' - - self.atmgridarray = atmgridarray - self.ocngridarray = ocngridarray - self.localdir = localdir - self.verbose = verbose - - if (os.path.isdir(localdir)): - logger.info(f'Prepare to download FIX data for {atmgrid} and {ocngrid} to {localdir}') - else: - logger.info(f'local dir: <{localdir}> does not exist. Stop') - sys.exit(-1) - - self.verdict = {} - self.s3dict = {} - self.s3dict['raworog'] = f'raw/orog' - - if (self.localdir.find('fix') < 0): - self.targetdir = f'{self.localdir}/fix.subset' - else: - self.targetdir = self.localdir - - # -------------------------------------------------------------------------- - def update_s3dict(self): - - self.update_s3dick_grid_independent() - self.add_grid_data() - - if (self.verbose): - self.printinfo() - - # -------------------------------------------------------------------------- - def update_s3dick_grid_independent(self): - - for key in self.fix_ver_dict.keys(): - val = self.fix_ver_dict[key] - if (key == 'aer_ver'): - self.s3dict['aer'] = f'aer/{val}' - elif (key == 'am_ver'): - self.s3dict['am'] = f'am/{val}' - elif (key == 'chem_ver'): - self.s3dict['fimdata_chem'] = f'chem/{val}/fimdata_chem' - self.s3dict['Emission_data'] = f'chem/{val}/Emission_data' - elif (key == 'datm_ver'): - self.s3dict['cfsr'] = f'datm/{val}/cfsr' - self.s3dict['gefs'] = f'datm/{val}/gefs' - self.s3dict['gfs'] = f'datm/{val}/gfs' - self.s3dict['mom6'] = f'datm/{val}/mom6' - elif (key == 'glwu_ver'): - self.s3dict['glwu'] = f'glwu/{val}' - elif (key == 'gsi_ver'): - self.s3dict['gsi'] = f'gsi/{val}' - elif (key == 'lut_ver'): - self.s3dict['lut'] = f'lut/{val}' - elif (key == 'mom6_ver'): - self.s3dict['mom6post'] = f'mom6/{val}/post' - elif (key == 'reg2grb2_ver'): - self.s3dict['reg2grb2'] = f'reg2grb2/{val}' - elif (key == 'sfc_climb_ver'): - self.s3dict['sfc_climo'] = f'sfc_climo/{val}' - elif (key == 'verif_ver'): - self.s3dict['verif'] = f'verif/{val}' - elif (key == 'wave_ver'): - self.s3dict['wave'] = f'wave/{val}' - - # -------------------------------------------------------------------------- - def add_grid_data(self): - - for key in self.fix_ver_dict.keys(): - val = self.fix_ver_dict[key] - if (key == 'orog_ver'): - self.add_atmgrid2s3dict('orog', key, val) - elif (key == 'ugwd_ver'): - self.add_atmgrid2s3dict('ugwd', key, val) - elif (key == 'mom6_ver'): - self.add_ocngrid2s3dict('mom6', key, val) - elif (key == 'cice_ver'): - self.add_ocngrid2s3dict('cice', key, val) - elif (key == 'cpl_ver'): - self.add_cpl2s3dict('cpl', key, val) - - # -------------------------------------------------------------------------- - def add_atmgrid2s3dict(self, varname, key, val): - - for atmgrid in self.atmgridarray: - newkey = f'{key}_{atmgrid}' - self.s3dict[newkey] = f'{varname}/{val}/{atmgrid}' - - # ------------------------------------------------------------------------- - def add_ocngrid2s3dict(self, varname, key, val): - - for ocngrid in self.ocngridarray: - newkey = f'{key}_{atmgrid}' - self.s3dict[newkey] = f'{varname}/{val}/{ocngrid}' - - # ------------------------------------------------------------------------- - def add_cpl2s3dict(self, varname, key, val): - - for atmgrid in self.atmgridarray: - for ocngrid in self.ocngridarray: - newkey = f'{key}_a{atmgrid}o{ocngrid}' - self.s3dict[newkey] = f'{varname}/{val}/a{atmgrid}o{ocngrid}' - - # ------------------------------------------------------------------------- - def printinfo(self): - - logger.info(f'Preparing to fetch') - logger.info(f'ATM grid: {self.atmgridarray}') - logger.info(f'ONC grid: {self.ocngridarray}') - logger.info(f'From: {self.aws_fix_bucket}') - logger.info(f'To: {self.targetdir}') - for key in self.s3dict.keys(): - val = self.s3dict[key] - logger.info(f'{key}: {val}') - - # ------------------------------------------------------------------------- - def fetchdata(self): - - if (self.verbose): - logger.info(f'Create local fix dir: {self.targetdir}') - - path = Path(self.targetdir) - path.mkdir(parents=True, exist_ok=True) - - self.fetch_ugwp_limb_tau() - - for key in self.s3dict.keys(): - self.fetch_dir(self.s3dict[key]) - - # ------------------------------------------------------------------------- - def fetch_dir(self, dir): - - remotedir = f'{self.aws_fix_bucket}/{dir}' - localdir = f'{self.targetdir}/{dir}' - cmd = f'{self.aws_sync} {remotedir} {localdir}' - self.download_dir(cmd, localdir) - - # -------------------------------------------------------------------------- - def download_dir(self, cmd, localdir): - - # returned_value = os.system(cmd) # returns the exit code in unix - # logger.info('returned value:', returned_value) - - if (os.path.isdir(localdir)): - logger.info(f'{localdir} already exist. skip') - else: - parentdir, dirname = os.path.split(localdir) - if (self.verbose): - logger.info(f'Create local {parentdir} dir:') - path = Path(parentdir) - path.mkdir(parents=True, exist_ok=True) - if (self.verbose): - logger.info(cmd) - logger.info(f'Downloading {localdir}') - returned_value = subprocess.call(cmd, shell=True) # returns the exit code in unix - if (self.verbose): - logger.info('returned value:', returned_value) - - # -------------------------------------------------------------------------- - def fetch_ugwp_limb_tau(self): - - ugwd_ver = self.fix_ver_dict['ugwd_ver'] - ugwp_limb_tau_remotepath = f'{self.aws_fix_bucket}/ugwd/{ugwd_ver}/ugwp_limb_tau.nc' - ugwp_limb_tau_localdir = f'{self.targetdir}/ugwd/{ugwd_ver}' - filename = f'{ugwp_limb_tau_localdir}/ugwp_limb_tau.nc' - path = Path(ugwp_limb_tau_localdir) - path.mkdir(parents=True, exist_ok=True) - cmd = f'{self.aws_cp} {ugwp_limb_tau_remotepath} {filename}' - self.download_file(cmd, filename) - - # ------------------------------------------------------------------------- - def download_file(self, cmd, filename): - - # returned_value = os.system(cmd) # returns the exit code in unix - # logger.info('returned value:', returned_value) - - if (os.path.isfile(filename)): - logger.info(f'{filename} already exist. skip') - else: - if (self.verbose): - logger.info(cmd) - logger.info(f'Downloading {filename}') - returned_value = subprocess.call(cmd, shell=True) # returns the exit code in unix - if (self.verbose): - logger.info('returned value:', returned_value) - - # -------------------------------------------------------------------------- - def set_fix_ver_from_gwhome(self, gwhome, verdict): - - fix_ver_file = f'{gwhome}/versions/fix.ver' - self.fix_ver_dict = verdict - if (os.path.isfile(fix_ver_file)): - with open(fix_ver_file, "r") as file: - for line in file.readlines(): - if (line.find('export ') >= 0): - headstr, _, value = line.strip().partition('=') - exphead, _, key = headstr.partition(' ') - self.fix_ver_dict[key] = value - else: - logger.info(f'fix_ver_file: {fix_ver_file}s does not exist.') - - # ------------------------------------------------------------------------ - def set_default_fix_ver(self, verdict): - - self.fix_ver_dict = verdict - -# ----------------------------------------------------------------------------- - - -def namespace_to_dict(namespace): - return { - k: namespace_to_dict(v) if isinstance(v, argparse.Namespace) else v - for k, v in vars(namespace).items() - } - -# ------------------------------------------------------------------------------ - - -if __name__ == '__main__': - - atmgridlist = ['C48', 'C96', 'C192', 'C384', 'C768', 'C1152'] - ocngridlist = ['500', '100', '050', '025'] - - parser = argparse.ArgumentParser() - parser.add_argument("-v", "--verbose", action="store_true", - help="increase output verbosity") - parser.add_argument("-a", "--atmgrid", type=str, required=True, - help="ATM grid, like: C48, C96, C192, C384, C768, C1152") - parser.add_argument("-o", "--ocngrid", type=str, required=True, - help="OCN grid, like: 500, 100, 050, 025") - parser.add_argument("--localdir", type=str, required=True, - help="local directory to store FIX data subset") - parser.add_argument("--gwhome", type=str, default='unknown', - help="GW home diretory where can find fix.ver") - parser.add_argument("--fix_bucket", type=str, default='s3://noaa-nws-global-pds/fix', - help="S3 Bucket directory of FIX data") - parser.add_argument("--aer_ver", type=str, default='20220805', help="AER version") - parser.add_argument("--am_ver", type=str, default='20220805', help="AM version") - parser.add_argument("--chem_ver", type=str, default='20220805', help="chem version") - parser.add_argument("--cice_ver", type=str, default='20240416', help="cice version") - parser.add_argument("--cpl_ver", type=str, default='20230526', help="cpl version") - parser.add_argument("--datm_ver", type=str, default='20220805', help="datm version") - parser.add_argument("--glwu_ver", type=str, default='20220805', help="glwu version") - parser.add_argument("--gsi_ver", type=str, default='20240208', help="gsi version") - parser.add_argument("--lut_ver", type=str, default='20220805', help="lut version") - parser.add_argument("--mom6_ver", type=str, default='20240416', help="mom6 version") - parser.add_argument("--orog_ver", type=str, default='20231027', help="orog version") - parser.add_argument("--reg2grb2_ver", type=str, default='20220805', help="reg2grb2 version") - parser.add_argument("--sfc_climo_ver", type=str, default='20220805', help="sfc_climo version") - parser.add_argument("--ugwd_ver", type=str, default='20220805', help="ugwd version") - parser.add_argument("--verif_ver", type=str, default='20220805', help="verif version") - parser.add_argument("--wave_ver", type=str, default='20220805', help="wave version") - args = parser.parse_args() - - if args.verbose: - logger.info(f"the atmgrid is {args.atmgrid}") - else: - logger.info(f"the atmgrid is {args.atmgrid}") - - atmgrid = args.atmgrid - if (atmgrid.find(',') > 0): - atmgridarray = atmgrid.split(',') - else: - atmgridarray = [atmgrid] - - for grid in atmgridarray: - if (grid not in atmgridlist): - logger.info(f'atmgrid: {grid}') - logger.info(f'is not in supported grids: {atmgridlist}') - sys.exit(-1) - - ocngrid = args.ocngrid - if (ocngrid.find(',') > 0): - ocngridarray = ocngrid.split(',') - else: - ocngridarray = [ocngrid] - - for grid in ocngridarray: - if (grid not in ocngridlist): - logger.info(f'ocngrid: {grid}') - logger.info(f'is not in supported grids: {ocngridlist}') - sys.exit(-1) - - verdict = namespace_to_dict(args) - - # ------------------------------------------------------------------ - ffd = FetchFIXdata(atmgridarray=atmgridarray, - ocngridarray=ocngridarray, - fix_bucket=args.fix_bucket, - localdir=args.localdir, verbose=args.verbose) - - if (args.gwhome is None): - ffd.set_default_fix_ver(verdict) - else: - ffd.set_fix_ver_from_gwhome(args.gwhome, verdict) - - ffd.update_s3dict() - ffd.fetchdata() From 0970ecb9176d7bb46809f2c6f03ba76d7ab0db65 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Thu, 27 Mar 2025 20:42:16 +0000 Subject: [PATCH 43/44] SHELL="/bin/bash" --- workflow/rocoto/workflow_xml.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/workflow/rocoto/workflow_xml.py b/workflow/rocoto/workflow_xml.py index 9b9ca306657..716ca84d0c2 100644 --- a/workflow/rocoto/workflow_xml.py +++ b/workflow/rocoto/workflow_xml.py @@ -175,13 +175,6 @@ def _write_crontab(self, crontab_file: str = None, cronint: int = 5) -> None: f'#################### {self.pslot} ####################' ] - # AWS need 'SHELL', and 'BASH_ENV' defined, or, the crontab job won't start. - if os.environ.get('PW_CSP', None) in ['aws', 'azure', 'google']: - crontab_strings.extend([ - 'SHELL="/bin/bash"', - 'BASH_ENV="/etc/bashrc"' - ]) - # Construct the crontab or scrontab if self.use_scrontab: # The slurm crontab needs an SCRON entry that calls a script @@ -216,6 +209,7 @@ def _write_crontab(self, crontab_file: str = None, cronint: int = 5) -> None: else: cron_cmd = rocotorunstr crontab_strings.extend([ + 'SHELL="/bin/bash"', f'MAILTO="{replyto}"' ]) From 3a3f195e898bf279a18762a7c85e83266fd09711 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Fri, 28 Mar 2025 15:52:20 +0000 Subject: [PATCH 44/44] Now build_compute.sh needs account name --- ci/Jenkinsfile4AWS | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/ci/Jenkinsfile4AWS b/ci/Jenkinsfile4AWS index c9872f90ca0..899558087cb 100644 --- a/ci/Jenkinsfile4AWS +++ b/ci/Jenkinsfile4AWS @@ -24,7 +24,6 @@ pipeline { stages { // This initial stage is used to get the Machine name from the GitHub labels on the PR // which is used to designate the Nodes in the Jenkins Controller by the agent label // Each Jenkins Node is connected to said machine via an JAVA agent via an ssh tunnel - // no op 2 stage('1. Get Machine') { agent { label 'built-in' } @@ -37,6 +36,7 @@ pipeline { } def run_nodes = [] + def machine_names = [] if (isSpawnedFromAnotherJob) { echo "machine being set to value passed to this spawned job" echo "passed machine: ${params.machine}" @@ -44,32 +44,33 @@ pipeline { } else { echo "This is parent job so getting list of nodes matching labels:" for (label in pullRequest.labels) { - echo "Checking label: ${label}" + echo "label in pullReqest: ${label}" if (label.matches("CI-(.*?)-Ready")) { + echo "Found Ready Label: ${label}" def machine_name = label.split('-')[1].toString().toLowerCase() - print machine_name jenkins.model.Jenkins.get().computers.each { c -> - print c.node.selfLabel.name if (c.node.selfLabel.name == NodeName[machine_name]) { run_nodes.add(c.node.selfLabel.name) + machine_names.add(machine_name) // record machine name alongside node } } } } - // Spawning all the jobs on the nodes matching the labels + // Spawning jobs using both run_nodes and machine_names arrays if (run_nodes.size() > 1) { - run_nodes.init().each { node -> - def machine_name = node.split('-')[0].toLowerCase() + for (int i = 0; i < run_nodes.size() - 1; i++) { + def node = run_nodes[i] + def machine_name = machine_names[i] // use the corresponding machine name echo "Spawning job on node: ${node} with machine name: ${machine_name}" build job: "/${aws_gw_name}/AWS-EPIC-Global-Workflow-Pipeline/PR-${env.CHANGE_ID}", parameters: [ string(name: 'machine', value: machine_name), - string(name: 'Node', value: node) ], - wait: false + string(name: 'Node', value: node) + ], wait: false } - machine = run_nodes.last().split('-')[0].toLowerCase() + machine = machine_names[run_nodes.size() - 1] echo "Running parent job: ${machine}" } else { - machine = run_nodes[0].split('-')[0].toLowerCase() + machine = machine_names[0] echo "Running only the parent job: ${machine}" } } @@ -81,10 +82,11 @@ pipeline { agent { label NodeName[machine].toLowerCase() } steps { script { + // Capitalize the first letter of the machine name and use if for labels Machine = machine[0].toUpperCase() + machine.substring(1) echo "Getting Common Workspace for ${Machine}" ws("${custom_workspace[machine]}/${env.CHANGE_ID}") { - properties([parameters([[$class: 'NodeParameterDefinition', allowedSlaves: ['built-in', 'Hercules-EMC', 'Hera-EMC', 'Orion-EMC', 'Gaea', 'Awsepicglobalworkflow'], defaultSlaves: ['built-in'], name: '', nodeEligibility: [$class: 'AllNodeEligibility'], triggerIfResult: 'allCases']])]) + properties([parameters([[$class: 'NodeParameterDefinition', allowedSlaves: ['built-in', 'Hercules-EMC', 'Hera-EMC', 'Orion-EMC', 'GaeaC5', 'GaeaC6-EMC', 'Awsepicglobalworkflow'], defaultSlaves: ['built-in'], name: '', nodeEligibility: [$class: 'AllNodeEligibility'], triggerIfResult: 'allCases']])]) GH = sh(script: "which gh || echo '~/bin/gh'", returnStdout: true).trim() CUSTOM_WORKSPACE = "${custom_workspace[machine]}/${env.CHANGE_ID}/${aws_gw_name}" HOMEgfs = "${CUSTOM_WORKSPACE}/${aws_gw_name}" @@ -132,7 +134,8 @@ pipeline { def error_logs_message = "" dir("${HOMEgfs}/sorc") { try { - sh(script: './build_compute.sh gfs gefs sfs') // build the global-workflow executables + // sh(script: "${HOMEgfs}/ci/scripts/utils/ci_utils_wrapper.sh build_compute") // build the global-workflow executables + sh(script: './build_compute.sh -A ${USER} gfs gefs sfs') // build the global-workflow executables } catch (Exception error_build) { echo "Failed to build global-workflow: ${error_build.getMessage()}" if ( fileExists("logs/error.logs") ) { @@ -152,13 +155,13 @@ pipeline { try { sh(script: """ source ${HOMEgfs}/workflow/gw_setup.sh - ${HOMEgfs}/ci/scripts/utils/publish_logs.py --file ${error_logs} --repo PR_BUILD_${env.CHANGE_ID} + ${HOMEgfs}/ci/scripts/utils/publish_logs.py --file ${error_logs} --gist PR_BUILD_${env.CHANGE_ID} | tail -n 1 """) gist_url=sh(script: """ source ${HOMEgfs}/workflow/gw_setup.sh ${HOMEgfs}/ci/scripts/utils/publish_logs.py --file ${error_logs} --gist PR_BUILD_${env.CHANGE_ID} """, returnStdout: true).trim() - sh(script: """${GH} pr comment ${env.CHANGE_ID} --repo ${repo_url} --body "Build **FAILED** on **${Machine}** in Build# ${env.BUILD_NUMBER} with error logs:\n\\`\\`\\`\n${error_logs_message}\\`\\`\\`\n\nFollow link here to view the contents of the above file(s): [(link)](${gist_url})" """) + sh(script: """${GH} pr comment ${env.CHANGE_ID} --repo ${repo_url} --body 'Build **FAILED** on **${Machine}** in Build# ${env.BUILD_NUMBER} with error logs:\n```\n${error_logs_message}```\n\nFollow link here to view the contents of the above file(s): [(link)](${gist_url})' """) } catch (Exception error_comment) { echo "Failed to comment on PR: ${error_comment.getMessage()}" }