From 2c0332abb56dae4c182053b873a14b0d88f4ce27 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 14 Jun 2023 12:05:34 -0600 Subject: [PATCH 01/57] update diff util and test that changes properly diff failling diffs, ci-run-diff --- .github/parm/use_case_groups.json | 4 +- metplus/util/diff_util.py | 422 +++++++++++++++++++----------- 2 files changed, 265 insertions(+), 161 deletions(-) diff --git a/.github/parm/use_case_groups.json b/.github/parm/use_case_groups.json index 0d5e34a9eb..a6fdaf3129 100644 --- a/.github/parm/use_case_groups.json +++ b/.github/parm/use_case_groups.json @@ -7,7 +7,7 @@ { "category": "met_tool_wrapper", "index_list": "30-58", - "run": false + "run": true }, { "category": "air_quality_and_comp", @@ -227,7 +227,7 @@ { "category": "tc_and_extra_tc", "index_list": "0-2", - "run": false + "run": true }, { "category": "tc_and_extra_tc", diff --git a/metplus/util/diff_util.py b/metplus/util/diff_util.py index 611732ab9b..a77f9df8c7 100755 --- a/metplus/util/diff_util.py +++ b/metplus/util/diff_util.py @@ -1,9 +1,13 @@ +#! /usr/bin/env python3 + +import sys import os import netCDF4 import filecmp import csv from PIL import Image, ImageChops import numpy +from numpy.core._exceptions import UFuncTypeError IMAGE_EXTENSIONS = [ '.jpg', @@ -37,6 +41,7 @@ # Note: Completing METplus issue #1873 could allow this to be set to 6 ROUNDING_PRECISION = 5 + def get_file_type(filepath): _, file_extension = os.path.splitext(filepath) @@ -55,7 +60,7 @@ def get_file_type(filepath): try: netCDF4.Dataset(filepath) return 'netcdf' - except: + except OSError: pass if file_extension in SKIP_EXTENSIONS: @@ -81,63 +86,69 @@ def compare_dir(dir_a, dir_b, debug=False, save_diff=False): return [result] diff_files = [] - for root, _, files in os.walk(dir_a): - # skip logs directories - if root.endswith('logs'): + for filepath_a in _get_files(dir_a): + filepath_b = filepath_a.replace(dir_a, dir_b) + print("\n# # # # # # # # # # # # # # # # # # # # # # # # # # " + "# # # #\n") + rel_path = filepath_a.replace(f'{dir_a}/', '') + print(f"COMPARING {rel_path}") + result = compare_files(filepath_a, + filepath_b, + debug=debug, + dir_a=dir_a, + dir_b=dir_b, + save_diff=save_diff) + + # no differences of skipped + if result is None or result is True: continue - for filename in files: - filepath_a = os.path.join(root, filename) + diff_files.append(result) - # skip directories - if not os.path.isfile(filepath_a): - continue + # loop through dir_b and report if any files are not found in dir_a + for filepath_b in _get_files(dir_b): + filepath_a = filepath_b.replace(dir_b, dir_a) + if os.path.exists(filepath_a): + continue + # check if missing file is actually diff file that was generated + diff_list = [item[3] for item in diff_files] + if filepath_b in diff_list: + continue + print(f"ERROR: File does not exist: {filepath_a}") + diff_files.append(('', filepath_b, 'file not found (new output)', '')) - # skip final conf file - if 'metplus_final.conf' in os.path.basename(filepath_a): - continue + print('::endgroup::') - filepath_b = filepath_a.replace(dir_a, dir_b) - print("\n# # # # # # # # # # # # # # # # # # # # # # # # # # " - "# # # #\n") - rel_path = filepath_a.replace(f'{dir_a}/', '') - print(f"COMPARING {rel_path}") - result = compare_files(filepath_a, - filepath_b, - debug=debug, - dir_a=dir_a, - dir_b=dir_b, - save_diff=save_diff) + _print_dir_summary(diff_files) + return diff_files - # no differences of skipped - if result is None or result is True: - continue - diff_files.append(result) +def _get_files(search_dir): + """!Generator to get all files in a directory. + Skips directories that end with 'logs' and files named metplus_final.conf - # loop through dir_b and report if any files are not found in dir_a - for root, _, files in os.walk(dir_b): + @param search_dir directory to search recursively + """ + for root, _, files in os.walk(search_dir): # skip logs directories if root.endswith('logs'): continue for filename in files: - filepath_b = os.path.join(root, filename) + filepath = os.path.join(root, filename) + + # skip directories + if not os.path.isfile(filepath): + continue # skip final conf file - if 'metplus_final.conf' in os.path.basename(filepath_b): + if 'metplus_final.conf' in os.path.basename(filepath): continue - filepath_a = filepath_b.replace(dir_b, dir_a) - if not os.path.exists(filepath_a): - # check if missing file is actually diff file that was generated - diff_list = [item[3] for item in diff_files] - if filepath_b in diff_list: - continue - print(f"ERROR: File does not exist: {filepath_a}") - diff_files.append(('', filepath_b, 'file not found (new output)', '')) + yield filepath - print('::endgroup::') + +def _print_dir_summary(diff_files): print("\n\n**************************************************\nSummary:\n") if diff_files: print("\nERROR: Some differences were found") @@ -151,7 +162,6 @@ def compare_dir(dir_a, dir_b, debug=False, save_diff=False): print("Finished comparing directories\n" "**************************************************\n\n") - return diff_files def compare_files(filepath_a, filepath_b, debug=False, dir_a=None, dir_b=None, @@ -178,47 +188,16 @@ def compare_files(filepath_a, filepath_b, debug=False, dir_a=None, dir_b=None, return filepath_a, filepath_b, file_type, '' if file_type == 'csv': - print('Comparing CSV') - if not compare_csv_files(filepath_a, filepath_b): - print(f'ERROR: CSV file differs: {filepath_b}') - return filepath_a, filepath_b, 'CSV diff', '' - - print("No differences in CSV files") - return True + return _handle_csv_files(filepath_a, filepath_b) if file_type == 'netcdf': - print("Comparing NetCDF") - if not nc_is_equal(filepath_a, filepath_b): - return filepath_a, filepath_b, 'NetCDF diff', '' - - print("No differences in NetCDF files") - return True + return _handle_netcdf_files(filepath_a, filepath_b) if file_type == 'pdf': - print("Comparing PDF as images") - diff_file = compare_pdf_as_images(filepath_a, filepath_b, - save_diff=save_diff) - if diff_file is True: - print("No differences in PDF files") - return True - - if diff_file is False: - diff_file = '' - - return filepath_a, filepath_b, 'PDF diff', diff_file + return _handle_pdf_files(filepath_a, filepath_b, save_diff) if file_type == 'image': - print("Comparing images") - diff_file = compare_image_files(filepath_a, filepath_b, - save_diff=save_diff) - if diff_file is True: - print("No differences in image files") - return True - - if diff_file is False: - diff_file = '' - - return filepath_a, filepath_b, 'Image diff', diff_file + return _handle_image_files(filepath_a, filepath_b, save_diff) # if not any of the above types, use diff to compare print("Comparing text files") @@ -236,6 +215,53 @@ def compare_files(filepath_a, filepath_b, debug=False, dir_a=None, dir_b=None, return True +def _handle_csv_files(filepath_a, filepath_b): + print('Comparing CSV') + if not compare_csv_files(filepath_a, filepath_b): + print(f'ERROR: CSV file differs: {filepath_b}') + return filepath_a, filepath_b, 'CSV diff', '' + + print("No differences in CSV files") + return True + + +def _handle_netcdf_files(filepath_a, filepath_b): + print("Comparing NetCDF") + if not nc_is_equal(filepath_a, filepath_b): + return filepath_a, filepath_b, 'NetCDF diff', '' + + print("No differences in NetCDF files") + return True + + +def _handle_pdf_files(filepath_a, filepath_b, save_diff): + print("Comparing PDF as images") + diff_file = compare_pdf_as_images(filepath_a, filepath_b, + save_diff=save_diff) + if diff_file is True: + print("No differences in PDF files") + return True + + if diff_file is False: + diff_file = '' + + return filepath_a, filepath_b, 'PDF diff', diff_file + + +def _handle_image_files(filepath_a, filepath_b, save_diff): + print("Comparing images") + diff_file = compare_image_files(filepath_a, filepath_b, + save_diff=save_diff) + if diff_file is True: + print("No differences in image files") + return True + + if diff_file is False: + diff_file = '' + + return filepath_a, filepath_b, 'Image diff', diff_file + + def compare_pdf_as_images(filepath_a, filepath_b, save_diff=False): try: from pdf2image import convert_from_path @@ -307,15 +333,20 @@ def compare_csv_files(filepath_a, filepath_b): lines_b = [] with open(filepath_a, 'r') as file_handle: - csv_read = csv.DictReader(file_handle, delimiter=',') - for row in csv_read: - lines_a.append(row) + lines_a.extend(csv.DictReader(file_handle, delimiter=',')) with open(filepath_b, 'r') as file_handle: - csv_read = csv.DictReader(file_handle, delimiter=',') - for row in csv_read: - lines_b.append(row) + lines_b.extend(csv.DictReader(file_handle, delimiter=',')) + # compare header values and number of lines + if not _compare_csv_lengths(lines_a, lines_b): + return False + + # compare each CSV column + return _compare_csv_columns(lines_a, lines_b) + + +def _compare_csv_lengths(lines_a, lines_b): keys_a = lines_a[0].keys() keys_b = lines_b[0].keys() # compare header columns and report error if they differ @@ -337,7 +368,11 @@ def compare_csv_files(filepath_a, filepath_b): f'than in OUTPUT ({len(lines_b)})') return False - # compare each CSV column + return True + + +def _compare_csv_columns(lines_a, lines_b): + keys_a = lines_a[0].keys() status = True for num, (line_a, line_b) in enumerate(zip(lines_a, lines_b), start=1): for key in keys_a: @@ -349,7 +384,7 @@ def compare_csv_files(filepath_a, filepath_b): # ROUNDING_PRECISION decimal places # METplus issue #1873 addresses the real problem try: - if is_equal_rounded(val_a, val_b): + if _is_equal_rounded(val_a, val_b): continue print(f"ERROR: Line {num} - {key} differs by " f"less than {ROUNDING_PRECISION} decimals: " @@ -364,7 +399,7 @@ def compare_csv_files(filepath_a, filepath_b): return status -def is_equal_rounded(value_a, value_b): +def _is_equal_rounded(value_a, value_b): if _truncate_float(value_a) == _truncate_float(value_b): return True if _round_float(value_a) == _round_float(value_b): @@ -425,10 +460,8 @@ def compare_txt_files(filepath_a, filepath_b, dir_a=None, dir_b=None): if is_stat_file: print("Comparing stat file") header_a = lines_a.pop(0).split()[1:] - header_b = lines_b.pop(0).split()[1:] else: header_a = None - header_b = None if len(lines_a) != len(lines_b): print(f"ERROR: Different number of lines in {filepath_b}") @@ -475,110 +508,181 @@ def diff_text_lines(lines_a, lines_b, compare_b = compare_b.replace(dir_b, dir_a) # check for differences - if compare_a != compare_b: - # if the diff is in a stat file, ignore the version number - if is_stat_file: - cols_a = compare_a.split()[1:] - cols_b = compare_b.split()[1:] - for col_a, col_b, label in zip(cols_a, cols_b, header_a): - if col_a != col_b: - if print_error: - print(f"ERROR: {label} differs:\n" - f" A: {col_a}\n B: {col_b}") - all_good = False - else: - if print_error: - print(f"ERROR: Line differs\n" - f" A: {compare_a}\n B: {compare_b}") + if compare_a == compare_b: + continue + + # if the diff is in a stat file, ignore the version number + if is_stat_file: + if not _diff_stat_line(compare_a, compare_b, header_a, print_error=print_error): all_good = False + continue + + if print_error: + print(f"ERROR: Line differs\n" + f" A: {compare_a}\n B: {compare_b}") + all_good = False + + return all_good + + +def _diff_stat_line(compare_a, compare_b, header_a, print_error=False): + """Compare values in .stat file. Ignore first column which contains MET + version number + + @param compare_a list of values in line A + @param compare_b list of values in line B + @param header_a list of header values in file A excluding MET version + @param print_error If True, print an error message if any value differs + """ + cols_a = compare_a.split()[1:] + cols_b = compare_b.split()[1:] + all_good = True + for col_a, col_b, label in zip(cols_a, cols_b, header_a): + if col_a == col_b: + continue + if print_error: + print(f"ERROR: {label} differs:\n" + f" A: {col_a}\n B: {col_b}") + all_good = False return all_good def nc_is_equal(file_a, file_b, fields=None, debug=False): """! Check if two NetCDF files have the same data - @param file_a first file to compare - @param file_b second file to compare - @param fields (Optional) list of fields to compare. If unset, compare - all fields - @returns True if all values in fields are equivalent, False if not + + @param file_a first file to compare + @param file_b second file to compare + @param fields (Optional) list of fields to compare. If unset, compare all + @param debug (optional) boolean to output more information about diff + @returns True if all values in fields are equivalent, False if not """ nc_a = netCDF4.Dataset(file_a) nc_b = netCDF4.Dataset(file_b) + # keep track of any differences that are found + is_equal = True + # if no fields are specified, get all of them if fields: - if not isinstance(fields, list): - field_list = [fields] - else: - field_list = fields + field_list = [fields] if not isinstance(fields, list) else fields else: a_fields = sorted(nc_a.variables.keys()) b_fields = sorted(nc_b.variables.keys()) + # fail if any fields exist in 1 file and not the other if a_fields != b_fields: print("ERROR: Field list differs between files\n" f" File_A: {a_fields}\n File_B:{b_fields}\n" f"Using File_A fields.") + is_equal = False field_list = a_fields # loop through fields, keeping track of any differences - is_equal = True - try: - for field in field_list: - var_a = nc_a.variables[field] - var_b = nc_b.variables[field] - - if debug: - print(f"Field: {field}") - print(f"Var_A:{var_a}\nVar_B:{var_b}") - print(f"Instance type: {type(var_a[0])}") - try: - values_a = var_a[:] - values_b = var_b[:] - values_diff = values_a - values_b - if (numpy.isnan(values_diff.min()) and - numpy.isnan(values_diff.max())): - print(f"WARNING: Variable {field} contains NaN values. " - "Cannot perform comparison.") - elif values_diff.min() != 0.0 or values_diff.max() != 0.0: - print(f"ERROR: Field ({field}) values differ\n" - f"Min diff: {values_diff.min()}, " - f"Max diff: {values_diff.max()}") - is_equal = False - # print indices that are not zero and count of diffs - if debug: - count = 0 - values_list = [j for sub in values_diff.tolist() - for j in sub] - for idx, val in enumerate(values_list): - if val != 0.0: - print(f"{idx}: {val}") - count += 1 - print(f"{count} / {idx+1} points differ") - - except: - # handle non-numeric fields - try: - if any(var_a[:].flatten() != var_b[:].flatten()): - print(f"ERROR: Field ({field}) values (non-numeric) " - "differ\n" - f" File_A: {var_a[:]}\n File_B: {var_b[:]}") - is_equal = False - except: - print("ERROR: Couldn't diff NetCDF files, need to update diff method") - is_equal = False + for field in field_list: + if not _nc_fields_are_equal(field, nc_a, nc_b, debug=debug): + is_equal = False + return is_equal + + +def _nc_fields_are_equal(field, nc_a, nc_b, debug=False): + """!Compare same field from 2 NetCDF files. + + @param field name of field to compare + @param nc_a first netCDF4.Dataset + @param nc_b first netCDF4.Dataset + @param debug (optional) boolean to output more information about diff + @returns True is fields are equal, False if fields are not equal or if + field is not found in one of the files + """ + try: + var_a = nc_a.variables[field] + var_b = nc_b.variables[field] except KeyError: print(f"ERROR: Field {field} not found") return False - return is_equal + if debug: + print(f"Field: {field}") + print(f"Var_A:{var_a}\nVar_B:{var_b}") + print(f"Instance type: {type(var_a[0])}") + + values_a = var_a[:] + values_b = var_b[:] + try: + values_diff = values_a - values_b + except (UFuncTypeError, TypeError): + # handle non-numeric fields + if not _all_values_are_equal(var_a, var_b): + print(f"ERROR: Field ({field}) values (non-numeric) " + "differ\n" + f" File_A: {var_a[:]}\n File_B: {var_b[:]}") + return False + + return True + + # if any NaN values in either data set, min and max of diff will be NaN + # compare each value + if numpy.isnan(values_diff.min()) and numpy.isnan(values_diff.max()): + print(f"Variable {field} contains NaN. Comparing each value...") + if not _all_values_are_equal(var_a, var_b): + print(f'ERROR: Some values differ in {field}') + return False + return True + + # consider all values equal is min and max diff are 0 + if not values_diff.min() and not values_diff.max(): + return True + + print(f"ERROR: Field ({field}) values differ\n" + f"Min diff: {values_diff.min()}, " + f"Max diff: {values_diff.max()}") + if debug: + # print indices that are not zero and count of diffs + _print_nc_field_diff_summary(values_diff) + + return False + + +def _print_nc_field_diff_summary(values_diff): + """!Print summary of NetCDF fields that differ. Prints the index of each + point that differs with the numeric difference between the points. + Also print number of points that differ and the total number of points. + + @param values_diff numpy array (possibly 2D) of differences + """ + count = 0 + values_list = [j for sub in values_diff.tolist() for j in sub] + for idx, val in enumerate(values_list): + if val != 0.0: + print(f"{idx}: {val}") + count += 1 + print(f"{count} / {idx + 1} points differ") + + +def _all_values_are_equal(var_a, var_b): + """!Compare each value to find differences. Handles case if both values + are NaN. + + @param var_a Numpy array + @param var_b Numpy array + @returns True if all values are equal, False otherwise + """ + for val_a, val_b in zip(var_a[:].flatten(), var_b[:].flatten()): + # continue to next value if both values are NaN + if numpy.isnan(val_a) and numpy.isnan(val_b): + continue + if val_a != val_b: + return False + return True if __name__ == '__main__': + if len(sys.argv) < 3: + print('ERROR: Must supply 2 directories to compare as arguments') + sys.exit(1) dir_a = sys.argv[1] dir_b = sys.argv[2] - if len(sys.argv) > 3: - save_diff = True + save_diff = len(sys.argv) > 3 compare_dir(dir_a, dir_b, debug=True, save_diff=save_diff) From 905b409bc16b5b8870b0202e8a820bb34e3f1735 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 14 Jun 2023 13:44:38 -0600 Subject: [PATCH 02/57] turn off use case --- .github/parm/use_case_groups.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/parm/use_case_groups.json b/.github/parm/use_case_groups.json index a6fdaf3129..131e0eed72 100644 --- a/.github/parm/use_case_groups.json +++ b/.github/parm/use_case_groups.json @@ -137,7 +137,7 @@ { "category": "s2s", "index_list": "3", - "run": true + "run": false }, { "category": "s2s", From c2b6e3a37dc9d07307dc11560dc1705da2c6ae63 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 14 Jun 2023 13:48:25 -0600 Subject: [PATCH 03/57] catch any exception that occurs in NetCDF file diff, ci-skip-unit-tests --- metplus/util/diff_util.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/metplus/util/diff_util.py b/metplus/util/diff_util.py index a77f9df8c7..680f85fa6b 100755 --- a/metplus/util/diff_util.py +++ b/metplus/util/diff_util.py @@ -669,12 +669,16 @@ def _all_values_are_equal(var_a, var_b): @param var_b Numpy array @returns True if all values are equal, False otherwise """ - for val_a, val_b in zip(var_a[:].flatten(), var_b[:].flatten()): - # continue to next value if both values are NaN - if numpy.isnan(val_a) and numpy.isnan(val_b): - continue - if val_a != val_b: - return False + try: + for val_a, val_b in zip(var_a[:].flatten(), var_b[:].flatten()): + # continue to next value if both values are NaN + if numpy.isnan(val_a) and numpy.isnan(val_b): + continue + if val_a != val_b: + return False + except Exception as err: + print(f'ERROR: Exception occurred: {err}') + return False return True From 5fdee80f510df17d7765521dec95cc2cd766765c Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 14 Jun 2023 14:10:10 -0600 Subject: [PATCH 04/57] catch any exception from file diff instead of just in NetCDF diff, ci-skip-unit-tests --- metplus/util/diff_util.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/metplus/util/diff_util.py b/metplus/util/diff_util.py index 680f85fa6b..be63dd034c 100755 --- a/metplus/util/diff_util.py +++ b/metplus/util/diff_util.py @@ -92,12 +92,16 @@ def compare_dir(dir_a, dir_b, debug=False, save_diff=False): "# # # #\n") rel_path = filepath_a.replace(f'{dir_a}/', '') print(f"COMPARING {rel_path}") - result = compare_files(filepath_a, - filepath_b, - debug=debug, - dir_a=dir_a, - dir_b=dir_b, - save_diff=save_diff) + try: + result = compare_files(filepath_a, + filepath_b, + debug=debug, + dir_a=dir_a, + dir_b=dir_b, + save_diff=save_diff) + except Exception as err: + print(f"ERROR: Exception occurred in diff logic: {err}") + result = filepath_a, filepath_b, 'Exception in diff logic', '' # no differences of skipped if result is None or result is True: @@ -669,16 +673,12 @@ def _all_values_are_equal(var_a, var_b): @param var_b Numpy array @returns True if all values are equal, False otherwise """ - try: - for val_a, val_b in zip(var_a[:].flatten(), var_b[:].flatten()): - # continue to next value if both values are NaN - if numpy.isnan(val_a) and numpy.isnan(val_b): - continue - if val_a != val_b: - return False - except Exception as err: - print(f'ERROR: Exception occurred: {err}') - return False + for val_a, val_b in zip(var_a[:].flatten(), var_b[:].flatten()): + # continue to next value if both values are NaN + if numpy.isnan(val_a) and numpy.isnan(val_b): + continue + if val_a != val_b: + return False return True From 21af4b24d45bc7c461d0892d6fc563411a825e9b Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 14 Jun 2023 14:12:58 -0600 Subject: [PATCH 05/57] forgot to trigger diff, ci-run-diff, ci-skip-unit-tests --- metplus/util/diff_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metplus/util/diff_util.py b/metplus/util/diff_util.py index be63dd034c..437302eb13 100755 --- a/metplus/util/diff_util.py +++ b/metplus/util/diff_util.py @@ -627,7 +627,7 @@ def _nc_fields_are_equal(field, nc_a, nc_b, debug=False): return True # if any NaN values in either data set, min and max of diff will be NaN - # compare each value + # compare each value if numpy.isnan(values_diff.min()) and numpy.isnan(values_diff.max()): print(f"Variable {field} contains NaN. Comparing each value...") if not _all_values_are_equal(var_a, var_b): From 2172134b869ec6f3bf78be7f07b78db5e61fa9b5 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 14 Jun 2023 14:16:06 -0600 Subject: [PATCH 06/57] use pandas.isnull instead of numpy.isnan to prevent exceptions from occurring, ci-run-diff, ci-skip-unit-tests --- metplus/util/diff_util.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/metplus/util/diff_util.py b/metplus/util/diff_util.py index 437302eb13..f9ca1215f1 100755 --- a/metplus/util/diff_util.py +++ b/metplus/util/diff_util.py @@ -6,7 +6,7 @@ import filecmp import csv from PIL import Image, ImageChops -import numpy +from pandas import isnull from numpy.core._exceptions import UFuncTypeError IMAGE_EXTENSIONS = [ @@ -627,8 +627,8 @@ def _nc_fields_are_equal(field, nc_a, nc_b, debug=False): return True # if any NaN values in either data set, min and max of diff will be NaN - # compare each value - if numpy.isnan(values_diff.min()) and numpy.isnan(values_diff.max()): + # compare each value + if isnull(values_diff.min()) and isnull(values_diff.max()): print(f"Variable {field} contains NaN. Comparing each value...") if not _all_values_are_equal(var_a, var_b): print(f'ERROR: Some values differ in {field}') @@ -675,7 +675,7 @@ def _all_values_are_equal(var_a, var_b): """ for val_a, val_b in zip(var_a[:].flatten(), var_b[:].flatten()): # continue to next value if both values are NaN - if numpy.isnan(val_a) and numpy.isnan(val_b): + if isnull(val_a) and isnull(val_b): continue if val_a != val_b: return False From eefaa0c90eb71d0361941d7677f0a0d4efcd5cce Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 14 Jun 2023 14:41:49 -0600 Subject: [PATCH 07/57] capture failure in diff script, ci-run-diff, ci-skip-unit-tests --- .github/jobs/run_difference_tests.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/jobs/run_difference_tests.sh b/.github/jobs/run_difference_tests.sh index 49e7242ec8..333e0372e7 100755 --- a/.github/jobs/run_difference_tests.sh +++ b/.github/jobs/run_difference_tests.sh @@ -12,6 +12,7 @@ matrix_categories=$1 artifact_name=$2 .github/jobs/setup_and_run_diff.py ${matrix_categories} $artifact_name +ret=$? if [ "$( ls -A ${RUNNER_WORKSPACE}/diff)" ]; then echo "upload_diff=true" >> $GITHUB_OUTPUT @@ -21,3 +22,4 @@ if [ "$( ls -A ${RUNNER_WORKSPACE}/diff)" ]; then fi echo "upload_diff=false" >> $GITHUB_OUTPUT +return $ret \ No newline at end of file From 0201daa8df93dcfc75859ba62ce6728805cf40af Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 14 Jun 2023 14:46:22 -0600 Subject: [PATCH 08/57] ignore .idea directory that was auto-generated --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index a065a4e761..f62ca72792 100644 --- a/.gitignore +++ b/.gitignore @@ -88,6 +88,8 @@ ENV/ # pytest cache files *.pytest_cache* +.idea + # tilda files generated by emacs *~ From 194088d68f6e7bc4071e313619152903336648cc Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 14 Jun 2023 15:03:31 -0600 Subject: [PATCH 09/57] fix incorrect syntax, ci-run-diff, ci-skip-unit-tests --- .github/jobs/run_difference_tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/jobs/run_difference_tests.sh b/.github/jobs/run_difference_tests.sh index 333e0372e7..8112ad0ecf 100755 --- a/.github/jobs/run_difference_tests.sh +++ b/.github/jobs/run_difference_tests.sh @@ -22,4 +22,4 @@ if [ "$( ls -A ${RUNNER_WORKSPACE}/diff)" ]; then fi echo "upload_diff=false" >> $GITHUB_OUTPUT -return $ret \ No newline at end of file +exit $ret \ No newline at end of file From 8017d99c3d9c2471488300a225362490abaf7983 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 14 Jun 2023 16:13:58 -0600 Subject: [PATCH 10/57] handle failing comparison when NetCDF values are stored as a string, ci-run-diff, ci-skip-unit-tests --- metplus/util/diff_util.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/metplus/util/diff_util.py b/metplus/util/diff_util.py index f9ca1215f1..ccaac6846e 100755 --- a/metplus/util/diff_util.py +++ b/metplus/util/diff_util.py @@ -673,6 +673,11 @@ def _all_values_are_equal(var_a, var_b): @param var_b Numpy array @returns True if all values are equal, False otherwise """ + # if the values are stored as a string, compare them with == + if isinstance(var_a[:], str) or isinstance(var_b[:], str): + return var_a[:] == var_b[:] + + # flatten the numpy.ndarray and compare each value for val_a, val_b in zip(var_a[:].flatten(), var_b[:].flatten()): # continue to next value if both values are NaN if isnull(val_a) and isnull(val_b): From d7981f218aed398d66b81faac35f065a3a5146b0 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 14 Jun 2023 16:15:16 -0600 Subject: [PATCH 11/57] Preserve backwards compatibility by forcing TC_PAIRS_RUN_ONCE=False if LOOP_ORDER is still used and warn that it should be removed. Add debug log message to alert user that only the first init/valid time is being processed and how to change that if desired --- metplus/wrappers/tc_pairs_wrapper.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/metplus/wrappers/tc_pairs_wrapper.py b/metplus/wrappers/tc_pairs_wrapper.py index 61fad0a136..78377e4317 100755 --- a/metplus/wrappers/tc_pairs_wrapper.py +++ b/metplus/wrappers/tc_pairs_wrapper.py @@ -293,6 +293,22 @@ def create_c_dict(self): False) ) + # check for settings that cause differences moving from v4.1 to v5.0 + # warn and update run setting to preserve old behavior + if (self.config.has_option('config', 'LOOP_ORDER') and + self.config.getstr_nocheck('config', 'LOOP_ORDER') == 'times' and + not self.config.has_option('config', 'TC_PAIRS_RUN_ONCE')): + self.logger.warning( + 'LOOP_ORDER has been deprecated. LOOP_ORDER has been set to ' + '"times" and TC_PAIRS_RUN_ONCE is not set. ' + 'Forcing TC_PAIRS_RUN_ONCE=False to preserve behavior prior to ' + 'v5.0.0. Please remove LOOP_ORDER and set ' + 'TC_PAIRS_RUN_ONCE=False to preserve previous behavior and ' + 'remove this warning message.' + ) + c_dict['RUN_ONCE'] = False + return c_dict + # only run once if True c_dict['RUN_ONCE'] = self.config.getbool('config', 'TC_PAIRS_RUN_ONCE', @@ -318,6 +334,8 @@ def run_all_times(self): if not self.c_dict['RUN_ONCE']: return super().run_all_times() + self.logger.debug('Only processing first run time. Set ' + 'TC_PAIRS_RUN_ONCE=False to process all run times.') self.run_at_time(input_dict) return self.all_commands From c8a80b2bdd4c6c30322280dcf4eeceedb66fd62d Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 14 Jun 2023 16:17:38 -0600 Subject: [PATCH 12/57] add pandas to diff conda environment used for diff tests in GHA to properly check for null/NaN values --- internal/scripts/docker_env/scripts/diff_env.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/scripts/docker_env/scripts/diff_env.sh b/internal/scripts/docker_env/scripts/diff_env.sh index 92a59c1470..bb89248e0c 100755 --- a/internal/scripts/docker_env/scripts/diff_env.sh +++ b/internal/scripts/docker_env/scripts/diff_env.sh @@ -2,10 +2,11 @@ ################################################################################ # Environment: diff.v5.1 -# Last Updated: 2023-01-31 (mccabe@ucar.edu) +# Last Updated: 2023-06-14 (mccabe@ucar.edu) # Notes: Adds packages needed to run differences tests to compare output to # truth data. # Python Packages: +# pandas # pillow==9.2.0 # pdf2image==1.16.0 # @@ -23,6 +24,7 @@ ENV_NAME=diff.${METPLUS_VERSION} BASE_ENV=netcdf4.${METPLUS_VERSION} conda create -y --clone ${BASE_ENV} --name ${ENV_NAME} +conda install -y --name ${ENV_NAME} -c conda-forge pandas conda install -y --name ${ENV_NAME} -c conda-forge pillow==9.2.0 apt install -y poppler-utils From 353fd152d9cf5374860b3bd3a1044f8d99e71d79 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 14 Jun 2023 16:44:23 -0600 Subject: [PATCH 13/57] turn off use cases after tests succeeded --- .github/parm/use_case_groups.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/parm/use_case_groups.json b/.github/parm/use_case_groups.json index 131e0eed72..23ff852726 100644 --- a/.github/parm/use_case_groups.json +++ b/.github/parm/use_case_groups.json @@ -7,7 +7,7 @@ { "category": "met_tool_wrapper", "index_list": "30-58", - "run": true + "run": false }, { "category": "air_quality_and_comp", @@ -227,7 +227,7 @@ { "category": "tc_and_extra_tc", "index_list": "0-2", - "run": true + "run": false }, { "category": "tc_and_extra_tc", From 52f5cebef3b734986fd9a08195e740308d99f9f9 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 15 Jun 2023 10:55:24 -0600 Subject: [PATCH 14/57] update apt-get to fix poppler-utils install error, add specific version for pandas --- internal/scripts/docker_env/scripts/diff_env.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/internal/scripts/docker_env/scripts/diff_env.sh b/internal/scripts/docker_env/scripts/diff_env.sh index bb89248e0c..54544a38e8 100755 --- a/internal/scripts/docker_env/scripts/diff_env.sh +++ b/internal/scripts/docker_env/scripts/diff_env.sh @@ -6,7 +6,7 @@ # Notes: Adds packages needed to run differences tests to compare output to # truth data. # Python Packages: -# pandas +# pandas==2.0.2 # pillow==9.2.0 # pdf2image==1.16.0 # @@ -24,9 +24,10 @@ ENV_NAME=diff.${METPLUS_VERSION} BASE_ENV=netcdf4.${METPLUS_VERSION} conda create -y --clone ${BASE_ENV} --name ${ENV_NAME} -conda install -y --name ${ENV_NAME} -c conda-forge pandas +conda install -y --name ${ENV_NAME} -c conda-forge pandas==2.0.2 conda install -y --name ${ENV_NAME} -c conda-forge pillow==9.2.0 -apt install -y poppler-utils +apt-get update +apt-get install -y poppler-utils conda install -y --name ${ENV_NAME} -c conda-forge pdf2image==1.16.0 From 1421c18e5b01e37881c1a39fdfdbe0043327a762 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 15 Jun 2023 11:07:20 -0600 Subject: [PATCH 15/57] run use case to test that diff.v5.1 conda env was created properly, ci-run-diff --- .github/parm/use_case_groups.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/parm/use_case_groups.json b/.github/parm/use_case_groups.json index 23ff852726..6bae411ea5 100644 --- a/.github/parm/use_case_groups.json +++ b/.github/parm/use_case_groups.json @@ -157,7 +157,7 @@ { "category": "s2s_mid_lat", "index_list": "0-2", - "run": false + "run": true }, { "category": "s2s_mid_lat", From b29a7acc67d80c9107aca78e6641a154365cb23a Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 15 Jun 2023 11:23:04 -0600 Subject: [PATCH 16/57] check if values are completely equal inside _is_equal_rounded function, call that function in NC value diff to prevent differences that are smaller than 5 decimal places --- metplus/util/diff_util.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/metplus/util/diff_util.py b/metplus/util/diff_util.py index ccaac6846e..14efccf47c 100755 --- a/metplus/util/diff_util.py +++ b/metplus/util/diff_util.py @@ -382,8 +382,6 @@ def _compare_csv_columns(lines_a, lines_b): for key in keys_a: val_a = line_a[key] val_b = line_b[key] - if val_a == val_b: - continue # prevent error if values are diffs are less than # ROUNDING_PRECISION decimal places # METplus issue #1873 addresses the real problem @@ -404,6 +402,8 @@ def _compare_csv_columns(lines_a, lines_b): def _is_equal_rounded(value_a, value_b): + if value_a == value_b: + return True if _truncate_float(value_a) == _truncate_float(value_b): return True if _round_float(value_a) == _round_float(value_b): @@ -682,7 +682,8 @@ def _all_values_are_equal(var_a, var_b): # continue to next value if both values are NaN if isnull(val_a) and isnull(val_b): continue - if val_a != val_b: + if not _is_equal_rounded(val_a, val_b): + print(f'val_a: {val_a}, val_b: {val_b}') return False return True From 2b9bea52580fca1621a94958bf18fa91728980db Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 15 Jun 2023 13:35:26 -0600 Subject: [PATCH 17/57] turn off all use case groups before re-opening PR --- .github/parm/use_case_groups.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/parm/use_case_groups.json b/.github/parm/use_case_groups.json index 6bae411ea5..23ff852726 100644 --- a/.github/parm/use_case_groups.json +++ b/.github/parm/use_case_groups.json @@ -157,7 +157,7 @@ { "category": "s2s_mid_lat", "index_list": "0-2", - "run": true + "run": false }, { "category": "s2s_mid_lat", From 0cbcff25c134e7379696a58e9d2e0693cd7d53db Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 15 Jun 2023 17:16:08 -0600 Subject: [PATCH 18/57] if both netcdf values are masked, consider them equal --- metplus/util/diff_util.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/metplus/util/diff_util.py b/metplus/util/diff_util.py index 14efccf47c..f26ba790f2 100755 --- a/metplus/util/diff_util.py +++ b/metplus/util/diff_util.py @@ -7,6 +7,7 @@ import csv from PIL import Image, ImageChops from pandas import isnull +from numpy.ma import is_masked from numpy.core._exceptions import UFuncTypeError IMAGE_EXTENSIONS = [ @@ -680,7 +681,7 @@ def _all_values_are_equal(var_a, var_b): # flatten the numpy.ndarray and compare each value for val_a, val_b in zip(var_a[:].flatten(), var_b[:].flatten()): # continue to next value if both values are NaN - if isnull(val_a) and isnull(val_b): + if (isnull(val_a) and isnull(val_b)) or (is_masked(val_a) and is_masked(val_b)): continue if not _is_equal_rounded(val_a, val_b): print(f'val_a: {val_a}, val_b: {val_b}') From 70e5b5e9e64fa7c4d7a8f31f498b7a773d3918cb Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Fri, 16 Jun 2023 12:04:06 -0600 Subject: [PATCH 19/57] updates to the wrapper to properly set the -data arguments --- .../wrappers/tc_diag/test_tc_diag_wrapper.py | 23 +-- metplus/wrappers/tc_diag_wrapper.py | 153 ++++++++++++------ .../met_tool_wrapper/TCDiag/TCDiag.conf | 30 +++- 3 files changed, 142 insertions(+), 64 deletions(-) diff --git a/internal/tests/pytests/wrappers/tc_diag/test_tc_diag_wrapper.py b/internal/tests/pytests/wrappers/tc_diag/test_tc_diag_wrapper.py index faddf14e20..d62db8b247 100644 --- a/internal/tests/pytests/wrappers/tc_diag/test_tc_diag_wrapper.py +++ b/internal/tests/pytests/wrappers/tc_diag/test_tc_diag_wrapper.py @@ -9,7 +9,7 @@ deck_template = 'aal14{date?fmt=%Y}_short.dat' input_template = 'gfs.subset.t00z.pgrb2.0p25.f*' -output_template = 'tc_diag_aal14{date?fmt=%Y}.nc' +output_template = '{date?fmt=%Y}' time_fmt = '%Y%m%d%H' run_times = ['2016092900'] @@ -24,6 +24,9 @@ '{ name="TMP"; level="P100"; }];' ) +input_domain = 'parent' +input_tech_id_list = 'GFSO' + def get_data_dir(config): return os.path.join(config.getdir('METPLUS_BASE'), @@ -46,9 +49,11 @@ def set_minimum_config_settings(config): config.set('config', 'TC_DIAG_CONFIG_FILE', '{PARM_BASE}/met_config/TCDiagConfig_wrapped') config.set('config', 'TC_DIAG_DECK_TEMPLATE', deck_template) - config.set('config', 'TC_DIAG_INPUT_TEMPLATE', input_template) + config.set('config', 'TC_DIAG_INPUT1_TEMPLATE', input_template) + config.set('config', 'TC_DIAG_INPUT1_DOMAIN', input_domain) + config.set('config', 'TC_DIAG_INPUT1_TECH_ID_LIST', input_tech_id_list) config.set('config', 'TC_DIAG_OUTPUT_DIR', - '{OUTPUT_BASE}/TCDiag/output') + '{OUTPUT_BASE}/tc_diag') config.set('config', 'TC_DIAG_OUTPUT_TEMPLATE', output_template) config.set('config', 'BOTH_VAR1_NAME', 'PRMSL') @@ -231,13 +236,11 @@ def test_tc_diag_run(metplus_config, config_overrides, config_file = wrapper.c_dict.get('CONFIG_FILE') out_dir = wrapper.c_dict.get('OUTPUT_DIR') - expected_cmds = [(f"{app_path} " - f"-deck {deck_dir}/aal142016_short.dat " - f"-data {file_list_file} " - f"-config {config_file} " - f"-out {out_dir}/tc_diag_aal142016.nc " - f"{verbosity}"), - ] + expected_cmds = [ + (f"{app_path} -deck {deck_dir}/aal142016_short.dat " + f"-data {input_domain} {input_tech_id_list} {file_list_file} " + f"-config {config_file} -outdir {out_dir}/2016/ {verbosity}"), + ] all_cmds = wrapper.run_all_times() print(f"ALL COMMANDS: {all_cmds}") diff --git a/metplus/wrappers/tc_diag_wrapper.py b/metplus/wrappers/tc_diag_wrapper.py index e2c49a013c..1b8ebd8a75 100755 --- a/metplus/wrappers/tc_diag_wrapper.py +++ b/metplus/wrappers/tc_diag_wrapper.py @@ -15,7 +15,8 @@ from ..util import time_util from . import RuntimeFreqWrapper from ..util import do_string_sub, skip_time, get_lead_sequence -from ..util import parse_var_list, sub_var_list +from ..util import parse_var_list, sub_var_list, getlist +from ..util import find_indices_in_config_section from ..util.met_config import add_met_config_dict_list '''!@namespace TCDiagWrapper @@ -85,29 +86,28 @@ def create_c_dict(self): self.log_error('Only RUN_ONCE_PER_INIT_OR_VALID is supported for ' 'TC_DIAG_RUNTIME_FREQ.') - # get the MET config file path or use default - c_dict['CONFIG_FILE'] = self.get_config_file('TCDiagConfig_wrapped') + # get command line arguments domain and tech id list for -data + self._read_data_inputs(c_dict) - c_dict['INPUT_DIR'] = self.config.getdir('TC_DIAG_INPUT_DIR', '') - c_dict['INPUT_TEMPLATE'] = self.config.getraw('config', - 'TC_DIAG_INPUT_TEMPLATE') - c_dict['INPUT_FILE_LIST'] = self.config.getraw( - 'config', 'TC_DIAG_INPUT_FILE_LIST' + # get -deck argument dir/template + c_dict['DECK_INPUT_DIR'] = self.config.getdir('TC_DIAG_DECK_INPUT_DIR', + '') + c_dict['DECK_INPUT_TEMPLATE'] = ( + self.config.getraw('config', + 'TC_DIAG_DECK_TEMPLATE') ) + # get output dir/template c_dict['OUTPUT_DIR'] = self.config.getdir('TC_DIAG_OUTPUT_DIR', '') c_dict['OUTPUT_TEMPLATE'] = ( self.config.getraw('config', 'TC_DIAG_OUTPUT_TEMPLATE') ) - c_dict['DECK_INPUT_DIR'] = self.config.getdir('TC_DIAG_DECK_INPUT_DIR', - '') - c_dict['DECK_INPUT_TEMPLATE'] = ( - self.config.getraw('config', - 'TC_DIAG_DECK_TEMPLATE') - ) + # get the MET config file path or use default + c_dict['CONFIG_FILE'] = self.get_config_file('TCDiagConfig_wrapped') + # get variables to set in wrapped MET config file self.add_met_config(name='model', data_type='list', metplus_configs=['TC_DIAG_MODEL', 'MODEL']) @@ -232,23 +232,78 @@ def create_c_dict(self): return c_dict + def _read_data_inputs(self, c_dict): + """! Parse the -data arguments from the METplusConfig object. + Sets c_dict DATA_INPUTS key with a list of dictionaries. + Each input should include domain, tech_id_list, and dir/template. + Logs error if any required variables are not set. + + @param c_dict dictionary to save values into + """ + # get template indices + indices = list( + find_indices_in_config_section(r'TC_DIAG_INPUT(\d+)_TEMPLATE$', + self.config, + index_index=1).keys() + ) + + # if no template indices were found, look for file list indices + if not indices: + indices = list( + find_indices_in_config_section(r'TC_DIAG_INPUT(\d+)_FILE_LIST$', + self.config, + index_index=1).keys() + ) + # error if no file list or template indices were found + if not indices: + self.log_error( + 'Must set TC_DIAG_INPUT_TEMPLATE/DOMAIN/TECH_ID_LIST' + ) + return + + c_dict['DATA_INPUTS'] = [] + for index in indices: + prefix = f'TC_DIAG_INPUT{index}_' + directory = self.config.getdir(f'{prefix}DIR') + template = self.config.getraw('config', f'{prefix}TEMPLATE') + + # get file list if template is not set + if template: + file_list = None + else: + file_list = self.config.getraw('config', f'{prefix}FILE_LIST') + + domain = self.config.getraw('config', f'{prefix}DOMAIN') + if not domain: + self.log_error(f'Must set {prefix}DOMAIN') + + tech_id_list = getlist( + self.config.getraw('config', f'{prefix}TECH_ID_LIST') + ) + if not tech_id_list: + self.log_error(f'Must set {prefix}TECH_ID_LIST') + + data_dict = { + 'template': template, + 'directory': directory, + 'file_list': file_list, + 'domain': domain, + 'tech_id_list': tech_id_list, + } + c_dict['DATA_INPUTS'].append(data_dict) + def get_command(self): cmd = self.app_path # add deck cmd += ' -deck ' + self.c_dict['DECK_FILE'] - # add input files - cmd += ' -data' - for infile in self.infiles: - cmd += ' ' + infile - # add arguments cmd += ' ' + ' '.join(self.args) # add output path out_path = self.get_output_path() - cmd += ' -out ' + out_path + cmd += ' -outdir ' + out_path # add verbosity cmd += ' -v ' + self.c_dict['VERBOSITY'] @@ -259,13 +314,15 @@ def run_at_time_once(self, time_info): Args: @param time_info dictionary containing timing information """ + self.clear() time_info = time_util.ti_calculate(time_info) + # get input files - if self.find_input_files(time_info) is None: + if not self.find_input_files(time_info): return # get output path - if not self.find_and_check_output_file(time_info): + if not self.find_and_check_output_file(time_info, is_directory=True): return # get field information to set in MET config @@ -281,12 +338,6 @@ def run_at_time_once(self, time_info): # set environment variables if using config file self.set_environment_variables(time_info) - # build command and run - cmd = self.get_command() - if cmd is None: - self.log_error("Could not generate command") - return - self.build() def set_data_field(self, time_info): @@ -327,47 +378,57 @@ def find_input_files(self, time_info): # get deck file deck_file = self.find_data(time_info, data_type='DECK') if not deck_file: - return None - + return False self.c_dict['DECK_FILE'] = deck_file + # get files and values for -data arguments lead_seq = get_lead_sequence(self.config, time_info) + for data_dict in self.c_dict['DATA_INPUTS']: + if not self._find_data_inputs(data_dict, lead_seq, time_info, + deck_file): + return False + return True - # get input files - if self.c_dict['INPUT_FILE_LIST']: - self.logger.debug("Explicit file list file: " - f"{self.c_dict['INPUT_FILE_LIST']}") - list_file = do_string_sub(self.c_dict['INPUT_FILE_LIST'], - **time_info) + def _find_data_inputs(self, data_dict, lead_seq, time_info, deck_file): + # check if file list file is set and use that instead of template/dir + input_file_list = data_dict['file_list'] + if input_file_list: + self.logger.debug(f"Explicit file list file: {input_file_list}") + list_file = do_string_sub(input_file_list, **time_info) if not os.path.exists(list_file): self.log_error(f'Could not find file list: {list_file}') - return None + return False else: - all_input_files = [] + # set c_dict variables that are used in find_data function + self.c_dict['INPUT_DIR'] = data_dict['directory'] + self.c_dict['INPUT_TEMPLATE'] = data_dict['template'] + all_input_files = [] for lead in lead_seq: - self.clear() - time_info['lead'] = lead - - time_info = time_util.ti_calculate(time_info) + time_info_lead = time_info.copy() + time_info_lead['lead'] = lead + time_info_lead = time_util.ti_calculate(time_info_lead) # get a list of the input data files, # write to an ascii file if there are more than one - input_files = self.find_data(time_info, return_list=True) + input_files = self.find_data(time_info_lead, return_list=True) if not input_files: continue all_input_files.extend(input_files) if not all_input_files: - return None + return False # create an ascii file with a list of the input files list_file = f"{os.path.basename(deck_file)}_data_files.txt" list_file = self.write_list_file(list_file, all_input_files) - self.infiles.append(list_file) - return self.infiles + # build argument with file list file, domain, and tech id list + domain = data_dict['domain'] + tech_ids = ','.join(data_dict['tech_id_list']) + self.args.append(f'-data {domain} {tech_ids} {list_file}') + return True def set_lead_list(self, time_info): self.env_var_dict['METPLUS_LEAD_LIST'] = '' diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index 7f2bcc3b0e..494abb126f 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -40,11 +40,19 @@ INIT_INCREMENT = 21600 TC_DIAG_DECK_INPUT_DIR = {INPUT_BASE}/met_test/new/tc_data/adeck TC_DIAG_DECK_TEMPLATE = aal14{date?fmt=%Y}_short.dat -TC_DIAG_INPUT_DIR = {INPUT_BASE}/met_test/new/model_data/grib2/gfs_fv3 -TC_DIAG_INPUT_TEMPLATE = gfs.subset.t00z.pgrb2.0p25.f* +TC_DIAG_INPUT1_DIR = {INPUT_BASE}/met_test/new/model_data/grib2/gfs_fv3 +TC_DIAG_INPUT1_TEMPLATE = gfs.subset.t00z.pgrb2.0p25.f* +TC_DIAG_INPUT1_DOMAIN = parent +TC_DIAG_INPUT1_TECH_ID_LIST = GFSO -TC_DIAG_OUTPUT_DIR = {OUTPUT_BASE}/met_tool_wrapper/TCDiag -TC_DIAG_OUTPUT_TEMPLATE = tc_diag_aal14{date?fmt=%Y}.nc + +TC_DIAG_INPUT2_DIR = {INPUT_BASE}/met_test/new/model_data/grib2/gfs_fv3 +TC_DIAG_INPUT2_TEMPLATE = gfs.subset.t00z.pgrb2.0p25.f* +TC_DIAG_INPUT2_DOMAIN = nest +TC_DIAG_INPUT2_TECH_ID_LIST = GFSO + +TC_DIAG_OUTPUT_DIR = {OUTPUT_BASE}/tc_diag +TC_DIAG_OUTPUT_TEMPLATE = {date?fmt=%Y} ### @@ -84,12 +92,18 @@ TC_DIAG_CYCLONE = 14 #TC_DIAG_DIAG_SCRIPT = -#TC_DIAG_DOMAIN_INFO1_DOMAIN = -#TC_DIAG_DOMAIN_INFO1_N_RANGE = -#TC_DIAG_DOMAIN_INFO1_N_AZIMUTH = -#TC_DIAG_DOMAIN_INFO1_DELTA_RANGE_KM = +TC_DIAG_DOMAIN_INFO1_DOMAIN = parent +TC_DIAG_DOMAIN_INFO1_N_RANGE = 150 +TC_DIAG_DOMAIN_INFO1_N_AZIMUTH = 8 +TC_DIAG_DOMAIN_INFO1_DELTA_RANGE_KM = 10.0 #TC_DIAG_DOMAIN_INFO1_DIAG_SCRIPT = +TC_DIAG_DOMAIN_INFO2_DOMAIN = nest +TC_DIAG_DOMAIN_INFO2_N_RANGE = 150 +TC_DIAG_DOMAIN_INFO2_N_AZIMUTH = 8 +TC_DIAG_DOMAIN_INFO2_DELTA_RANGE_KM = 2.0 + + #TC_DIAG_CENSOR_THRESH = #TC_DIAG_CENSOR_VAL = #TC_DIAG_CONVERT = From 7dee5a9d57ed1ff4f427ee9eb05929b5b0d42359 Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Wed, 5 Jul 2023 17:22:43 -0400 Subject: [PATCH 20/57] Added some additional description to the 'Description' section for TC-DIAG in the METplus wrappers page, as the initial description seems overly terse. --- docs/Users_Guide/wrappers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Users_Guide/wrappers.rst b/docs/Users_Guide/wrappers.rst index 3432ba0210..eedfec39d5 100644 --- a/docs/Users_Guide/wrappers.rst +++ b/docs/Users_Guide/wrappers.rst @@ -7692,7 +7692,7 @@ TCDiag Description ----------- -Used to configure the MET tool TC-Diag. +The TC-Diag wrapper encapsulates the behavior of the MET `tc_diag `_ tool. It provides the infrastructure to compute diagnostics from model fields and tracks. It can be configured to run over a single intialization time, all of the initialization times for a given storm, or over many storms. Configuration also allows a user to select which domain(s) of the input model data to use in the diagnostics calculations, set which levels and variables will be used as well as details about the azimuth-range grid used for the calculations, and to control which output files are generated. Future functionality of the tc_diag tool, such as vortex removal, will also be configurable from this wrapper. METplus Configuration --------------------- From 2e39caaaef768580f0cf221c7c3dc15e11faf307 Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Wed, 5 Jul 2023 22:17:50 -0400 Subject: [PATCH 21/57] As per #2201 (for #1626), reviewed and enhanced the TC-Diag basic use case example documentation. --- .../met_tool_wrapper/TCDiag/TCDiag.py | 49 +++++++++++++++++-- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py b/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py index d2a8f0b75d..4133b5cc43 100644 --- a/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py +++ b/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py @@ -5,18 +5,50 @@ met_tool_wrapper/TCDiag/TCDiag.conf """ +############################################################################## +# Overview +# -------------------- +# +# This use case illustrates the use of tc_diag tool, which is currently +# considered a beta-level release that lacks full functionality. +# The use case illustrates running the +# tc_diag tool for a tropical cyclone forecast case and generating +# intermediate NetCDF output files of the input model's data transformed +# onto an azimuth-range grid. When the full functionality of the +# tc_diag tool is released in MET v12.0.0, this use case will be also +# output environmental diagnostics computed from callable Python scripts. +# +# The diagnostics are computed on a range-azimuth grid that follows the +# projected storm track. For inputs, it uses 0.25 deg gridded GRIB files from the +# a retrospective reforecast of the Global Forecast System Finite Volume (GFS-FV3). For the track, it uses the +# GFS-FV3's predicted track to ensure that the model's simulated storm doesn't +# contaminate the diagnostics result as a result of the model's simulated +# storm being mistaken for environmental factors. (Note: +# a future version of the tc_diag tool will include removal of the model's vortex, +# allowing diagnostics to be computed along any arbitrarily defined track.) +# + +# Novel aspects of this use case: +# +# This is the first example use case to run the tc_diag tool. +# Example of running for a single tropical cyclone forecast case from +# Hurricane Matthew (2016) using GFS-FV3 data. + ############################################################################## # Scientific Objective # -------------------- # -# TODO: Add content here +# Generate intermediate data files, in which the input model's data have been +# transformed to a range-azimuth grid, in preparation for further diagnostic +# calculations using Python-based routines. ############################################################################## # Datasets # -------- # -# **Forecast:** GFS FV3 -# **Track:** A Deck +# **Forecast:** GFS grib files +# +# **Track:** a-deck file (Automated Tropical Cyclone Forecast System format) # # **Location:** All of the input data required for this use case can be found # in the met_test sample data tarball. Click here to the METplus releases page @@ -26,6 +58,11 @@ # This tarball should be unpacked into the directory that you will set the # value of INPUT_BASE. See `Running METplus`_ section for more information. # +# **Data source:** Users may obtain real-time data from the deterministic GFS-FV3 runs from +# NOAA's NOMADS server: +# https://nomads.ncep.noaa.gov/pub/data/nccf/com/gfs/prod/gfs.YYYYMMDD/ZZ/atmos/ +# where YYYYMMDD is the date (4-digit year, 2-digit month, 2-digit day), +# ZZ is the initialization hour of the desired model cycle (00, 06, 12, 18). ############################################################################## # METplus Components @@ -42,8 +79,8 @@ # TCDiag is the only tool called in this example. It processes the following # run times: # -# **Init:** 2016-09-29- 00Z -# **Forecast lead:** 141, 143, and 147 hour +# **Init:** 2016-09-29 0000Z +# **Forecast lead:** 141, 144, and 147 hour # ############################################################################## @@ -107,6 +144,8 @@ # # * TCDiagToolUseCase # * GRIB2FileUseCase +# * TCandExtraTCAppUseCase +# * FeatureRelativeUseCase # # Navigate to the :ref:`quick-search` page to discover other similar use cases. # From a8395091ba6424b0c2c6450ee1d111a97d2665a7 Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Thu, 6 Jul 2023 17:30:53 -0400 Subject: [PATCH 22/57] Corrected link to MET config file. --- docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py b/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py index 4133b5cc43..40db70a544 100644 --- a/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py +++ b/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py @@ -104,7 +104,7 @@ # If there is a setting in the MET configuration file that is currently not supported by METplus you'd like to control, please refer to: # :ref:`Overriding Unsupported MET config file settings` # -# .. note:: See the :ref:`TCDiag MET Configuration` section of the User's Guide for more information on the environment variables used in the file below: +# .. note:: See the :ref:`TCDiag MET Configuration` section of the User's Guide for more information on the environment variables used in the file below: # # .. highlight:: bash # .. literalinclude:: ../../../../parm/met_config/TCDiagConfig_wrapped @@ -133,7 +133,8 @@ # Output for this use case will be found in met_tool_wrapper/TCDiag (relative to **OUTPUT_BASE**) # and will contain the following files: # -# * tc_diag_aal142016.nc +# * tc_diag_AL142016_fv3_2016092900_cyl_grid_nest.nc +# * tc_diag_AL142016_fv3_2016092900_cyl_grid_parent.nc # ############################################################################## @@ -142,10 +143,10 @@ # # .. note:: # +# * DiagnosticsUseCase # * TCDiagToolUseCase # * GRIB2FileUseCase -# * TCandExtraTCAppUseCase -# * FeatureRelativeUseCase +# * TCUseCase # # Navigate to the :ref:`quick-search` page to discover other similar use cases. # From e2756b78b3f15a43e7bd8e0c20661bede6e5e8f3 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 6 Jul 2023 15:45:12 -0600 Subject: [PATCH 23/57] add TropicalCycloneUseCase quick search keyword and add it the keyword to each relevant use case --- docs/Users_Guide/quicksearch.rst | 3 +++ docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py | 2 +- docs/use_cases/met_tool_wrapper/TCGen/TCGen.py | 1 + docs/use_cases/met_tool_wrapper/TCMPRPlotter/TCMPRPlotter.py | 1 + .../met_tool_wrapper/TCPairs/TCPairs_extra_tropical.py | 1 + docs/use_cases/met_tool_wrapper/TCPairs/TCPairs_tropical.py | 1 + docs/use_cases/met_tool_wrapper/TCRMW/TCRMW.py | 1 + docs/use_cases/met_tool_wrapper/TCStat/TCStat.py | 1 + ...riesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByInit.py | 1 + ...riesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByLead.py | 1 + ...eatureRelative_SeriesByLead_PyEmbed_Multiple_Diagnostics.py | 1 + .../CyclonePlotter_fcstGFS_obsGFS_UserScript_ExtraTC.py | 1 + .../tc_and_extra_tc/GridStat_fcstHAFS_obsTDR_NetCDF.py | 1 + .../tc_and_extra_tc/Plotter_fcstGFS_obsGFS_ExtraTC.py | 1 + .../tc_and_extra_tc/Plotter_fcstGFS_obsGFS_RPlotting.py | 1 + .../tc_and_extra_tc/TCGen_fcstGFS_obsBDECK_2021season.py | 1 + .../TCPairs_TCStat_fcstADECK_obsBDECK_ATCF_BasicExample.py | 1 + .../tc_and_extra_tc/TCRMW_fcstGFS_fcstOnly_gonzalo.py | 1 + .../UserScript_ASCII2NC_PointStat_fcstHAFS_obsFRD_NetCDF.py | 1 + 19 files changed, 21 insertions(+), 1 deletion(-) diff --git a/docs/Users_Guide/quicksearch.rst b/docs/Users_Guide/quicksearch.rst index 58caef38f2..f15c3e9b76 100644 --- a/docs/Users_Guide/quicksearch.rst +++ b/docs/Users_Guide/quicksearch.rst @@ -10,6 +10,7 @@ METplus Quick Search for Use Cases Use Cases by MET Tool: +====================== .. only:: html @@ -159,6 +160,7 @@ Use Cases by METplus Feature: | `Runtime Frequency <../search.html?q=RuntimeFreqUseCase&check_keywords=yes&area=default>`_ | `Series by Initialization <../search.html?q=SeriesByInitUseCase&check_keywords=yes&area=default>`_ | `Series by Forecast Lead <../search.html?q=SeriesByLeadUseCase&check_keywords=yes&area=default>`_ + | `Tropical Cyclone <../search.html?q=TropicalCycloneUseCase&check_keywords=yes&area=default>`_ | `Validation of Models or Analyses <../search.html?q=ValidationUseCase&check_keywords=yes&area=default>`_ | `User Defined Script <../search.html?q=UserScriptUseCase&check_keywords=yes&area=default>`_ @@ -187,6 +189,7 @@ Use Cases by METplus Feature: | **Runtime Frequency**: *RuntimeFreqUseCase* | **Series by Initialization**: *SeriesByInitUseCase* | **Series by Forecast Lead**: *SeriesByLeadUseCase* + | **Tropical Cyclone**: *TropicalCycloneUseCase* | **Validation of Models or Analyses**: *ValidationUseCase* | **User Defined Script**: *UserScriptUseCase* diff --git a/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py b/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py index 40db70a544..94bbd20a95 100644 --- a/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py +++ b/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py @@ -146,7 +146,7 @@ # * DiagnosticsUseCase # * TCDiagToolUseCase # * GRIB2FileUseCase -# * TCUseCase +# * TropicalCycloneUseCase # # Navigate to the :ref:`quick-search` page to discover other similar use cases. # diff --git a/docs/use_cases/met_tool_wrapper/TCGen/TCGen.py b/docs/use_cases/met_tool_wrapper/TCGen/TCGen.py index 1580255aa4..e3feba3fd2 100644 --- a/docs/use_cases/met_tool_wrapper/TCGen/TCGen.py +++ b/docs/use_cases/met_tool_wrapper/TCGen/TCGen.py @@ -124,6 +124,7 @@ # # * TCGenToolUseCase # * DTCOrgUseCase +# * TropicalCycloneUseCase # # Navigate to the :ref:`quick-search` page to discover other similar use cases. # diff --git a/docs/use_cases/met_tool_wrapper/TCMPRPlotter/TCMPRPlotter.py b/docs/use_cases/met_tool_wrapper/TCMPRPlotter/TCMPRPlotter.py index 34f456e36c..84a9ced20c 100644 --- a/docs/use_cases/met_tool_wrapper/TCMPRPlotter/TCMPRPlotter.py +++ b/docs/use_cases/met_tool_wrapper/TCMPRPlotter/TCMPRPlotter.py @@ -110,6 +110,7 @@ # .. note:: # # * TCMPRPlotterUseCase +# * TropicalCycloneUseCase # # Navigate to the :ref:`quick-search` page to discover other similar use cases. # diff --git a/docs/use_cases/met_tool_wrapper/TCPairs/TCPairs_extra_tropical.py b/docs/use_cases/met_tool_wrapper/TCPairs/TCPairs_extra_tropical.py index c685439818..0913065d7f 100644 --- a/docs/use_cases/met_tool_wrapper/TCPairs/TCPairs_extra_tropical.py +++ b/docs/use_cases/met_tool_wrapper/TCPairs/TCPairs_extra_tropical.py @@ -124,6 +124,7 @@ # # * TCPairsToolUseCase # * SBUOrgUseCase +# * TropicalCycloneUseCase # # Navigate to the :ref:`quick-search` page to discover other similar use cases. # diff --git a/docs/use_cases/met_tool_wrapper/TCPairs/TCPairs_tropical.py b/docs/use_cases/met_tool_wrapper/TCPairs/TCPairs_tropical.py index 9a9e174b61..e0cb0ab729 100644 --- a/docs/use_cases/met_tool_wrapper/TCPairs/TCPairs_tropical.py +++ b/docs/use_cases/met_tool_wrapper/TCPairs/TCPairs_tropical.py @@ -128,6 +128,7 @@ # # * TCPairsToolUseCase # * DTCOrgUseCase +# * TropicalCycloneUseCase # # Navigate to the :ref:`quick-search` page to discover other similar use cases. # diff --git a/docs/use_cases/met_tool_wrapper/TCRMW/TCRMW.py b/docs/use_cases/met_tool_wrapper/TCRMW/TCRMW.py index 8e7e468a2a..d3d3bdf40a 100644 --- a/docs/use_cases/met_tool_wrapper/TCRMW/TCRMW.py +++ b/docs/use_cases/met_tool_wrapper/TCRMW/TCRMW.py @@ -122,6 +122,7 @@ # # * TCRMWToolUseCase # * GRIB2FileUseCase +# * TropicalCycloneUseCase # # Navigate to the :ref:`quick-search` page to discover other similar use cases. # diff --git a/docs/use_cases/met_tool_wrapper/TCStat/TCStat.py b/docs/use_cases/met_tool_wrapper/TCStat/TCStat.py index 4c4d08d037..7386d9ee6f 100644 --- a/docs/use_cases/met_tool_wrapper/TCStat/TCStat.py +++ b/docs/use_cases/met_tool_wrapper/TCStat/TCStat.py @@ -120,6 +120,7 @@ # .. note:: # # * TCStatToolUseCase +# * TropicalCycloneUseCase # # Navigate to the :ref:`quick-search` page to discover other similar use cases. # diff --git a/docs/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByInit.py b/docs/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByInit.py index 4d6266a927..0dce153a7b 100644 --- a/docs/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByInit.py +++ b/docs/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByInit.py @@ -252,6 +252,7 @@ # * SBUOrgUseCase # * DiagnosticsUseCase # * RuntimeFreqUseCase +# * TropicalCycloneUseCase # # Navigate to the :ref:`quick-search` page to discover other similar use cases. # diff --git a/docs/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByLead.py b/docs/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByLead.py index e8bd1bbafa..eb93987e42 100644 --- a/docs/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByLead.py +++ b/docs/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByLead.py @@ -244,6 +244,7 @@ # * SBUOrgUseCase # * DiagnosticsUseCase # * RuntimeFreqUseCase +# * TropicalCycloneUseCase # # Navigate to the :ref:`quick-search` page to discover other similar use cases. # diff --git a/docs/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByLead_PyEmbed_Multiple_Diagnostics.py b/docs/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByLead_PyEmbed_Multiple_Diagnostics.py index f521ae9835..52808805f9 100644 --- a/docs/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByLead_PyEmbed_Multiple_Diagnostics.py +++ b/docs/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByLead_PyEmbed_Multiple_Diagnostics.py @@ -334,6 +334,7 @@ # * SBUOrgUseCase # * DiagnosticsUseCase # * RuntimeFreqUseCase +# * TropicalCycloneUseCase # # Navigate to the :ref:`quick-search` page to discover other similar use cases. # diff --git a/docs/use_cases/model_applications/tc_and_extra_tc/CyclonePlotter_fcstGFS_obsGFS_UserScript_ExtraTC.py b/docs/use_cases/model_applications/tc_and_extra_tc/CyclonePlotter_fcstGFS_obsGFS_UserScript_ExtraTC.py index ea52376bb1..22edf8e333 100644 --- a/docs/use_cases/model_applications/tc_and_extra_tc/CyclonePlotter_fcstGFS_obsGFS_UserScript_ExtraTC.py +++ b/docs/use_cases/model_applications/tc_and_extra_tc/CyclonePlotter_fcstGFS_obsGFS_UserScript_ExtraTC.py @@ -162,6 +162,7 @@ # * TCPairsToolUseCase # * SBUOrgUseCase # * CyclonePlotterUseCase +# * TropicalCycloneUseCase # # Navigate to the :ref:`quick-search` page to discover other similar use cases. # diff --git a/docs/use_cases/model_applications/tc_and_extra_tc/GridStat_fcstHAFS_obsTDR_NetCDF.py b/docs/use_cases/model_applications/tc_and_extra_tc/GridStat_fcstHAFS_obsTDR_NetCDF.py index ad6205e929..3a19f8abd0 100644 --- a/docs/use_cases/model_applications/tc_and_extra_tc/GridStat_fcstHAFS_obsTDR_NetCDF.py +++ b/docs/use_cases/model_applications/tc_and_extra_tc/GridStat_fcstHAFS_obsTDR_NetCDF.py @@ -152,6 +152,7 @@ # # * TCandExtraTCAppUseCase # * GridStatToolUseCase +# * TropicalCycloneUseCase # # Navigate to the :ref:`quick-search` page to discover other similar use cases. # diff --git a/docs/use_cases/model_applications/tc_and_extra_tc/Plotter_fcstGFS_obsGFS_ExtraTC.py b/docs/use_cases/model_applications/tc_and_extra_tc/Plotter_fcstGFS_obsGFS_ExtraTC.py index 8f10fbb482..a0fbb57a1d 100644 --- a/docs/use_cases/model_applications/tc_and_extra_tc/Plotter_fcstGFS_obsGFS_ExtraTC.py +++ b/docs/use_cases/model_applications/tc_and_extra_tc/Plotter_fcstGFS_obsGFS_ExtraTC.py @@ -139,6 +139,7 @@ # * NOAAEMCOrgUseCase # * SBUOrgUseCase # * DTCOrgUseCase +# * TropicalCycloneUseCase # # Navigate to the :ref:`quick-search` page to discover other similar use cases. # diff --git a/docs/use_cases/model_applications/tc_and_extra_tc/Plotter_fcstGFS_obsGFS_RPlotting.py b/docs/use_cases/model_applications/tc_and_extra_tc/Plotter_fcstGFS_obsGFS_RPlotting.py index d2aaaa4e20..f7ddd8c091 100644 --- a/docs/use_cases/model_applications/tc_and_extra_tc/Plotter_fcstGFS_obsGFS_RPlotting.py +++ b/docs/use_cases/model_applications/tc_and_extra_tc/Plotter_fcstGFS_obsGFS_RPlotting.py @@ -157,6 +157,7 @@ # * MediumRangeAppUseCase # * SBUOrgUseCase # * DTCOrgUseCase +# * TropicalCycloneUseCase # # Navigate to the :ref:`quick-search` page to discover other similar use cases. # diff --git a/docs/use_cases/model_applications/tc_and_extra_tc/TCGen_fcstGFS_obsBDECK_2021season.py b/docs/use_cases/model_applications/tc_and_extra_tc/TCGen_fcstGFS_obsBDECK_2021season.py index 307fb4a6d4..d66e08cb21 100644 --- a/docs/use_cases/model_applications/tc_and_extra_tc/TCGen_fcstGFS_obsBDECK_2021season.py +++ b/docs/use_cases/model_applications/tc_and_extra_tc/TCGen_fcstGFS_obsBDECK_2021season.py @@ -135,6 +135,7 @@ # .. note:: # # * TCGenToolUseCase +# * TropicalCycloneUseCase # # Navigate to the :ref:`quick-search` page to discover other similar use cases. # diff --git a/docs/use_cases/model_applications/tc_and_extra_tc/TCPairs_TCStat_fcstADECK_obsBDECK_ATCF_BasicExample.py b/docs/use_cases/model_applications/tc_and_extra_tc/TCPairs_TCStat_fcstADECK_obsBDECK_ATCF_BasicExample.py index 99df0976dc..f60d401898 100644 --- a/docs/use_cases/model_applications/tc_and_extra_tc/TCPairs_TCStat_fcstADECK_obsBDECK_ATCF_BasicExample.py +++ b/docs/use_cases/model_applications/tc_and_extra_tc/TCPairs_TCStat_fcstADECK_obsBDECK_ATCF_BasicExample.py @@ -149,6 +149,7 @@ # # * TCPairsToolUseCase # * TCStatToolUseCase +# * TropicalCycloneUseCase # # Navigate to the :ref:`quick-search` page to discover other similar use cases. # diff --git a/docs/use_cases/model_applications/tc_and_extra_tc/TCRMW_fcstGFS_fcstOnly_gonzalo.py b/docs/use_cases/model_applications/tc_and_extra_tc/TCRMW_fcstGFS_fcstOnly_gonzalo.py index 8bc43a8c78..ccad94908b 100644 --- a/docs/use_cases/model_applications/tc_and_extra_tc/TCRMW_fcstGFS_fcstOnly_gonzalo.py +++ b/docs/use_cases/model_applications/tc_and_extra_tc/TCRMW_fcstGFS_fcstOnly_gonzalo.py @@ -123,6 +123,7 @@ # # * TCRMWToolUseCase # * GRIB2FileUseCase +# * TropicalCycloneUseCase # # Navigate to the :ref:`quick-search` page to discover other similar use cases. # diff --git a/docs/use_cases/model_applications/tc_and_extra_tc/UserScript_ASCII2NC_PointStat_fcstHAFS_obsFRD_NetCDF.py b/docs/use_cases/model_applications/tc_and_extra_tc/UserScript_ASCII2NC_PointStat_fcstHAFS_obsFRD_NetCDF.py index 313bd0c8d3..8b24b5a671 100644 --- a/docs/use_cases/model_applications/tc_and_extra_tc/UserScript_ASCII2NC_PointStat_fcstHAFS_obsFRD_NetCDF.py +++ b/docs/use_cases/model_applications/tc_and_extra_tc/UserScript_ASCII2NC_PointStat_fcstHAFS_obsFRD_NetCDF.py @@ -164,6 +164,7 @@ # * UserScriptUseCase # * PointStatToolUseCase # * ASCII2NCToolUseCase +# * TropicalCycloneUseCase # # Navigate to the :ref:`quick-search` page to discover other similar use cases. # From 30927a9114f244415287382421afa624e12ec613 Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Thu, 6 Jul 2023 22:05:13 -0400 Subject: [PATCH 24/57] As per #1626, modified the use case to use data form a more recent storm (Bret 2023). --- .../met_tool_wrapper/TCDiag/TCDiag.py | 8 ++++---- .../met_tool_wrapper/TCDiag/TCDiag.conf | 18 +++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py b/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py index 94bbd20a95..6dddb13450 100644 --- a/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py +++ b/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py @@ -20,8 +20,8 @@ # # The diagnostics are computed on a range-azimuth grid that follows the # projected storm track. For inputs, it uses 0.25 deg gridded GRIB files from the -# a retrospective reforecast of the Global Forecast System Finite Volume (GFS-FV3). For the track, it uses the -# GFS-FV3's predicted track to ensure that the model's simulated storm doesn't +# a retrospective reforecast of the Global Forecast System (GFS). For the track, it uses the +# GFS's predicted track to ensure that the model's simulated storm doesn't # contaminate the diagnostics result as a result of the model's simulated # storm being mistaken for environmental factors. (Note: # a future version of the tc_diag tool will include removal of the model's vortex, @@ -32,7 +32,7 @@ # # This is the first example use case to run the tc_diag tool. # Example of running for a single tropical cyclone forecast case from -# Hurricane Matthew (2016) using GFS-FV3 data. +# Tropical Storm Bret (2023) using GFS data. ############################################################################## # Scientific Objective @@ -58,7 +58,7 @@ # This tarball should be unpacked into the directory that you will set the # value of INPUT_BASE. See `Running METplus`_ section for more information. # -# **Data source:** Users may obtain real-time data from the deterministic GFS-FV3 runs from +# **Data source:** Users may obtain real-time data from the deterministic GFS runs from # NOAA's NOMADS server: # https://nomads.ncep.noaa.gov/pub/data/nccf/com/gfs/prod/gfs.YYYYMMDD/ZZ/atmos/ # where YYYYMMDD is the date (4-digit year, 2-digit month, 2-digit day), diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index 494abb126f..a17a95e980 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -27,8 +27,8 @@ PROCESS_LIST = TCDiag LOOP_BY = INIT INIT_TIME_FMT = %Y%m%d%H -INIT_BEG = 2016092900 -INIT_END = 2016092900 +INIT_BEG = 2023062012 +INIT_END = 2023062012 INIT_INCREMENT = 21600 @@ -38,16 +38,16 @@ INIT_INCREMENT = 21600 ### TC_DIAG_DECK_INPUT_DIR = {INPUT_BASE}/met_test/new/tc_data/adeck -TC_DIAG_DECK_TEMPLATE = aal14{date?fmt=%Y}_short.dat +TC_DIAG_DECK_TEMPLATE = aal03{date?fmt=%Y}_subset.dat -TC_DIAG_INPUT1_DIR = {INPUT_BASE}/met_test/new/model_data/grib2/gfs_fv3 -TC_DIAG_INPUT1_TEMPLATE = gfs.subset.t00z.pgrb2.0p25.f* +TC_DIAG_INPUT1_DIR = {INPUT_BASE}/met_test/new/model_data/grib2/gfs +TC_DIAG_INPUT1_TEMPLATE = gfs.t12z.pgrb2.0p50.f* TC_DIAG_INPUT1_DOMAIN = parent TC_DIAG_INPUT1_TECH_ID_LIST = GFSO TC_DIAG_INPUT2_DIR = {INPUT_BASE}/met_test/new/model_data/grib2/gfs_fv3 -TC_DIAG_INPUT2_TEMPLATE = gfs.subset.t00z.pgrb2.0p25.f* +TC_DIAG_INPUT2_TEMPLATE = gfs.t12z.pgrb2.0p50.f* TC_DIAG_INPUT2_DOMAIN = nest TC_DIAG_INPUT2_TECH_ID_LIST = GFSO @@ -76,11 +76,11 @@ BOTH_VAR2_LEVELS = P1000, P900, P800, P700, P500, P100 TC_DIAG_CONFIG_FILE = {PARM_BASE}/met_config/TCDiagConfig_wrapped -MODEL = fv3 +MODEL = gfs -TC_DIAG_STORM_ID = AL142016 +TC_DIAG_STORM_ID = AL032023 TC_DIAG_BASIN = AL -TC_DIAG_CYCLONE = 14 +TC_DIAG_CYCLONE = 03 #TC_DIAG_INIT_INCLUDE = #TC_DIAG_VALID_BEG = From 30f84a54cc84c1c4a200a873309b816b0c2c69f1 Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Thu, 6 Jul 2023 22:12:07 -0400 Subject: [PATCH 25/57] As per #1626, found one more fv3 ref to remove. --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index a17a95e980..a2cd7f1005 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -46,7 +46,7 @@ TC_DIAG_INPUT1_DOMAIN = parent TC_DIAG_INPUT1_TECH_ID_LIST = GFSO -TC_DIAG_INPUT2_DIR = {INPUT_BASE}/met_test/new/model_data/grib2/gfs_fv3 +TC_DIAG_INPUT2_DIR = {INPUT_BASE}/met_test/new/model_data/grib2/gfs TC_DIAG_INPUT2_TEMPLATE = gfs.t12z.pgrb2.0p50.f* TC_DIAG_INPUT2_DOMAIN = nest TC_DIAG_INPUT2_TECH_ID_LIST = GFSO From 1a18c3609fe4db17fefe1b7261be86bae3c45f9d Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Thu, 6 Jul 2023 22:14:19 -0400 Subject: [PATCH 26/57] As per #1626, changing GFSO to AVNO. --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index a2cd7f1005..216239f353 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -43,13 +43,13 @@ TC_DIAG_DECK_TEMPLATE = aal03{date?fmt=%Y}_subset.dat TC_DIAG_INPUT1_DIR = {INPUT_BASE}/met_test/new/model_data/grib2/gfs TC_DIAG_INPUT1_TEMPLATE = gfs.t12z.pgrb2.0p50.f* TC_DIAG_INPUT1_DOMAIN = parent -TC_DIAG_INPUT1_TECH_ID_LIST = GFSO +TC_DIAG_INPUT1_TECH_ID_LIST = AVNO TC_DIAG_INPUT2_DIR = {INPUT_BASE}/met_test/new/model_data/grib2/gfs TC_DIAG_INPUT2_TEMPLATE = gfs.t12z.pgrb2.0p50.f* TC_DIAG_INPUT2_DOMAIN = nest -TC_DIAG_INPUT2_TECH_ID_LIST = GFSO +TC_DIAG_INPUT2_TECH_ID_LIST = AVNO TC_DIAG_OUTPUT_DIR = {OUTPUT_BASE}/tc_diag TC_DIAG_OUTPUT_TEMPLATE = {date?fmt=%Y} From 991d6ad8014655523b69bb48e8dc83d8571fa10e Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Thu, 6 Jul 2023 22:18:22 -0400 Subject: [PATCH 27/57] As per #1626, hmmm, the use case didn't work with AVNO. So now trying using a TECH of GFSO. --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index 216239f353..a2cd7f1005 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -43,13 +43,13 @@ TC_DIAG_DECK_TEMPLATE = aal03{date?fmt=%Y}_subset.dat TC_DIAG_INPUT1_DIR = {INPUT_BASE}/met_test/new/model_data/grib2/gfs TC_DIAG_INPUT1_TEMPLATE = gfs.t12z.pgrb2.0p50.f* TC_DIAG_INPUT1_DOMAIN = parent -TC_DIAG_INPUT1_TECH_ID_LIST = AVNO +TC_DIAG_INPUT1_TECH_ID_LIST = GFSO TC_DIAG_INPUT2_DIR = {INPUT_BASE}/met_test/new/model_data/grib2/gfs TC_DIAG_INPUT2_TEMPLATE = gfs.t12z.pgrb2.0p50.f* TC_DIAG_INPUT2_DOMAIN = nest -TC_DIAG_INPUT2_TECH_ID_LIST = AVNO +TC_DIAG_INPUT2_TECH_ID_LIST = GFSO TC_DIAG_OUTPUT_DIR = {OUTPUT_BASE}/tc_diag TC_DIAG_OUTPUT_TEMPLATE = {date?fmt=%Y} From fc5e1f3766ef8e0f6d5eea491c133d680100472e Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Mon, 10 Jul 2023 11:57:29 -0400 Subject: [PATCH 28/57] As per #2616, changed GFSO to AVNO. --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index a2cd7f1005..216239f353 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -43,13 +43,13 @@ TC_DIAG_DECK_TEMPLATE = aal03{date?fmt=%Y}_subset.dat TC_DIAG_INPUT1_DIR = {INPUT_BASE}/met_test/new/model_data/grib2/gfs TC_DIAG_INPUT1_TEMPLATE = gfs.t12z.pgrb2.0p50.f* TC_DIAG_INPUT1_DOMAIN = parent -TC_DIAG_INPUT1_TECH_ID_LIST = GFSO +TC_DIAG_INPUT1_TECH_ID_LIST = AVNO TC_DIAG_INPUT2_DIR = {INPUT_BASE}/met_test/new/model_data/grib2/gfs TC_DIAG_INPUT2_TEMPLATE = gfs.t12z.pgrb2.0p50.f* TC_DIAG_INPUT2_DOMAIN = nest -TC_DIAG_INPUT2_TECH_ID_LIST = GFSO +TC_DIAG_INPUT2_TECH_ID_LIST = AVNO TC_DIAG_OUTPUT_DIR = {OUTPUT_BASE}/tc_diag TC_DIAG_OUTPUT_TEMPLATE = {date?fmt=%Y} From e3436b6991f27325e9539b5e68ae99259959df00 Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Mon, 10 Jul 2023 15:20:44 -0400 Subject: [PATCH 29/57] As per #1626, running with LOG_LEVEL=DEBUG as per @georgemccabe's suggestion. --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index 216239f353..f941d2e7df 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -131,3 +131,5 @@ TC_DIAG_DOMAIN_INFO2_DELTA_RANGE_KM = 2.0 #TC_DIAG_NC_DIAG_FLAG = #TC_DIAG_CIRA_DIAG_FLAG = #TC_DIAG_OUTPUT_PREFIX = + +LOG_LEVEL=DEBUG \ No newline at end of file From 829b9659d64ba9741891c5d98f918c4b4a6685f6 Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Mon, 10 Jul 2023 15:28:17 -0400 Subject: [PATCH 30/57] As per #1626, changing input file template. --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index f941d2e7df..ea8fb4fe62 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -38,7 +38,7 @@ INIT_INCREMENT = 21600 ### TC_DIAG_DECK_INPUT_DIR = {INPUT_BASE}/met_test/new/tc_data/adeck -TC_DIAG_DECK_TEMPLATE = aal03{date?fmt=%Y}_subset.dat +TC_DIAG_DECK_TEMPLATE = aal03{date?fmt=%Y}.dat TC_DIAG_INPUT1_DIR = {INPUT_BASE}/met_test/new/model_data/grib2/gfs TC_DIAG_INPUT1_TEMPLATE = gfs.t12z.pgrb2.0p50.f* From 0179b00a95ba92b40fbff2a24ddefebb10a01ca7 Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Mon, 10 Jul 2023 16:48:58 -0400 Subject: [PATCH 31/57] As per @georgemccabe's suggestion, upping the logging verbosity for #1626. --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index ea8fb4fe62..9cd160166f 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -73,6 +73,7 @@ BOTH_VAR2_LEVELS = P1000, P900, P800, P700, P500, P100 ### #LOG_TC_DIAG_VERBOSITY = 2 +LOG_TC_DIAG_VERBOSITY = 5 TC_DIAG_CONFIG_FILE = {PARM_BASE}/met_config/TCDiagConfig_wrapped From a0c16fbede8f30a9805819d1590cfb06f6b83143 Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Mon, 10 Jul 2023 16:52:37 -0400 Subject: [PATCH 32/57] As per @georgemccabe's suggestion, also setting SCRUB_STAGING_DIR = False for #1626. --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index 9cd160166f..5a48cdd0f8 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -75,6 +75,9 @@ BOTH_VAR2_LEVELS = P1000, P900, P800, P700, P500, P100 #LOG_TC_DIAG_VERBOSITY = 2 LOG_TC_DIAG_VERBOSITY = 5 +# ToDo: Remove this when finished +SCRUB_STAGING_DIR = False + TC_DIAG_CONFIG_FILE = {PARM_BASE}/met_config/TCDiagConfig_wrapped MODEL = gfs From e50088b94a122729eeaecd734a4028fc854bc032 Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Mon, 10 Jul 2023 19:29:37 -0400 Subject: [PATCH 33/57] As per @georgemccabe's request for #1626, changing MODEL to GFSO. TC_DIAG_INPUT1_TECH_ID_LIST is still AVNO. --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index 5a48cdd0f8..f9e4b41eeb 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -80,7 +80,7 @@ SCRUB_STAGING_DIR = False TC_DIAG_CONFIG_FILE = {PARM_BASE}/met_config/TCDiagConfig_wrapped -MODEL = gfs +MODEL = GFSO TC_DIAG_STORM_ID = AL032023 TC_DIAG_BASIN = AL From 37c86e613adbc1cec629efcefa5773d1bc911499 Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Mon, 10 Jul 2023 19:39:58 -0400 Subject: [PATCH 34/57] As per #1626, setting TC_DIAG_INIT_INCLUDE = 2023062012 As it threw an error: ``` ERROR : ERROR : process_tracks() -> set the "init_inc" config option to select one of the 31 track initialization times between 2023061700 and 2023062412. ERROR : ``` @georgemccabe, it seems kind of redudant to have to set the init time twice (once through this setting and again through the BEGIN and END looper). Is this the expected behavior? --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index f9e4b41eeb..11876301b7 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -86,7 +86,7 @@ TC_DIAG_STORM_ID = AL032023 TC_DIAG_BASIN = AL TC_DIAG_CYCLONE = 03 -#TC_DIAG_INIT_INCLUDE = +TC_DIAG_INIT_INCLUDE = 2023062012 #TC_DIAG_VALID_BEG = #TC_DIAG_VALID_END = #TC_DIAG_VALID_INCLUDE_LIST = From 48e89550d6667eeb06289bc859bd155fdf4d739c Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Mon, 10 Jul 2023 19:50:46 -0400 Subject: [PATCH 35/57] #1626: @georgemccabe, I got it to run further, but it barfed when it couldn't find PRMSL/L0. As per: https://luckgrib.com/blog/2018/08/28/gfs-sea-level-pressure.html the GFS now has two sea level pressures. PRMSL is heavily smoothed, while MSLET is much closer to reality. So changing PRMSL to MSLET in this use case. --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index 11876301b7..8fc636cd60 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -60,7 +60,8 @@ TC_DIAG_OUTPUT_TEMPLATE = {date?fmt=%Y} # https://metplus.readthedocs.io/en/latest/Users_Guide/systemconfiguration.html#field-info ### -BOTH_VAR1_NAME = PRMSL +#BOTH_VAR1_NAME = PRMSL +BOTH_VAR1_NAME = MSLET BOTH_VAR1_LEVELS = L0 BOTH_VAR2_NAME = TMP From 64fc15ce74950b7a415ae47ca0b6a3a285ebaf7d Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Mon, 10 Jul 2023 20:08:16 -0400 Subject: [PATCH 36/57] @georgemccabe It seems that the "old" FV3-GFS data used "L0", but now "Z0" might be the correct level. I'm about to try it to see if this works. --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index 8fc636cd60..194a9291de 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -62,7 +62,7 @@ TC_DIAG_OUTPUT_TEMPLATE = {date?fmt=%Y} #BOTH_VAR1_NAME = PRMSL BOTH_VAR1_NAME = MSLET -BOTH_VAR1_LEVELS = L0 +BOTH_VAR1_LEVELS = Z0 BOTH_VAR2_NAME = TMP BOTH_VAR2_LEVELS = P1000, P900, P800, P700, P500, P100 From e3b05f7765a9bbe8bbd83b8b9519153472da2335 Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Mon, 10 Jul 2023 20:10:08 -0400 Subject: [PATCH 37/57] #1626 @georgemccabe. Using MSLET/Z0 didn't work. Now trying PRMSL/Z0. --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index 194a9291de..5d7c075449 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -60,8 +60,8 @@ TC_DIAG_OUTPUT_TEMPLATE = {date?fmt=%Y} # https://metplus.readthedocs.io/en/latest/Users_Guide/systemconfiguration.html#field-info ### -#BOTH_VAR1_NAME = PRMSL -BOTH_VAR1_NAME = MSLET +BOTH_VAR1_NAME = PRMSL +#BOTH_VAR1_NAME = MSLET BOTH_VAR1_LEVELS = Z0 BOTH_VAR2_NAME = TMP From 1895c3e1f954df65ce44e44c71b78c87de450082 Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Mon, 10 Jul 2023 20:13:53 -0400 Subject: [PATCH 38/57] #1626 and @georgemccabe: Trying specificying no level. --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index 5d7c075449..95629e7f70 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -62,7 +62,7 @@ TC_DIAG_OUTPUT_TEMPLATE = {date?fmt=%Y} BOTH_VAR1_NAME = PRMSL #BOTH_VAR1_NAME = MSLET -BOTH_VAR1_LEVELS = Z0 +BOTH_VAR1_LEVELS = BOTH_VAR2_NAME = TMP BOTH_VAR2_LEVELS = P1000, P900, P800, P700, P500, P100 From 2079e5bd25a86312ebc6b5be93f8bffa4669ee6e Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Tue, 11 Jul 2023 08:49:07 -0600 Subject: [PATCH 39/57] use Z0 for PRMSL level and use current init time for init_inc value --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index 95629e7f70..285ee7df7e 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -62,7 +62,7 @@ TC_DIAG_OUTPUT_TEMPLATE = {date?fmt=%Y} BOTH_VAR1_NAME = PRMSL #BOTH_VAR1_NAME = MSLET -BOTH_VAR1_LEVELS = +BOTH_VAR1_LEVELS = Z0 BOTH_VAR2_NAME = TMP BOTH_VAR2_LEVELS = P1000, P900, P800, P700, P500, P100 @@ -87,7 +87,7 @@ TC_DIAG_STORM_ID = AL032023 TC_DIAG_BASIN = AL TC_DIAG_CYCLONE = 03 -TC_DIAG_INIT_INCLUDE = 2023062012 +TC_DIAG_INIT_INCLUDE = {init?fmt=%Y%m%d%H} #TC_DIAG_VALID_BEG = #TC_DIAG_VALID_END = #TC_DIAG_VALID_INCLUDE_LIST = From 6f54c379f278453f3a74b701ee742435e7cc72e7 Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Tue, 11 Jul 2023 12:26:26 -0400 Subject: [PATCH 40/57] #1626: Using time templates instead of hard-coding the times. --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index 95629e7f70..f37c160869 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -41,13 +41,13 @@ TC_DIAG_DECK_INPUT_DIR = {INPUT_BASE}/met_test/new/tc_data/adeck TC_DIAG_DECK_TEMPLATE = aal03{date?fmt=%Y}.dat TC_DIAG_INPUT1_DIR = {INPUT_BASE}/met_test/new/model_data/grib2/gfs -TC_DIAG_INPUT1_TEMPLATE = gfs.t12z.pgrb2.0p50.f* +TC_DIAG_INPUT1_TEMPLATE = gfs.t{init?fmt=%H}z.pgrb2.0p50.f* TC_DIAG_INPUT1_DOMAIN = parent TC_DIAG_INPUT1_TECH_ID_LIST = AVNO TC_DIAG_INPUT2_DIR = {INPUT_BASE}/met_test/new/model_data/grib2/gfs -TC_DIAG_INPUT2_TEMPLATE = gfs.t12z.pgrb2.0p50.f* +TC_DIAG_INPUT2_TEMPLATE = gfs.t{init?fmt=%H}z.pgrb2.0p50.f* TC_DIAG_INPUT2_DOMAIN = nest TC_DIAG_INPUT2_TECH_ID_LIST = AVNO @@ -61,8 +61,7 @@ TC_DIAG_OUTPUT_TEMPLATE = {date?fmt=%Y} ### BOTH_VAR1_NAME = PRMSL -#BOTH_VAR1_NAME = MSLET -BOTH_VAR1_LEVELS = +BOTH_VAR1_LEVELS = Z0 BOTH_VAR2_NAME = TMP BOTH_VAR2_LEVELS = P1000, P900, P800, P700, P500, P100 @@ -87,7 +86,7 @@ TC_DIAG_STORM_ID = AL032023 TC_DIAG_BASIN = AL TC_DIAG_CYCLONE = 03 -TC_DIAG_INIT_INCLUDE = 2023062012 +TC_DIAG_INIT_INCLUDE = {init?fmt=%Y%m%d%H} #TC_DIAG_VALID_BEG = #TC_DIAG_VALID_END = #TC_DIAG_VALID_INCLUDE_LIST = From d3f9ca19e67dd73c1df55df36338e37008c3840e Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Tue, 11 Jul 2023 13:18:45 -0400 Subject: [PATCH 41/57] #1626: Trying LEAD_SEQ to limit the extent of the run. --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index 285ee7df7e..11a1bbb83f 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -30,7 +30,7 @@ INIT_TIME_FMT = %Y%m%d%H INIT_BEG = 2023062012 INIT_END = 2023062012 INIT_INCREMENT = 21600 - +LEAD_SEA = 0, 6, 12 ### # File I/O From 649367176e9e3225efa96206b8d1ce15d5f8ca31 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Tue, 11 Jul 2023 12:34:31 -0600 Subject: [PATCH 42/57] fixed typo in variable name --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index 11a1bbb83f..1cfd242eea 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -30,7 +30,7 @@ INIT_TIME_FMT = %Y%m%d%H INIT_BEG = 2023062012 INIT_END = 2023062012 INIT_INCREMENT = 21600 -LEAD_SEA = 0, 6, 12 +LEAD_SEQ = 0, 6, 12 ### # File I/O From 19d6bd26c86d1240566552140658d55f13b210a0 Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Tue, 11 Jul 2023 14:42:12 -0400 Subject: [PATCH 43/57] #1626: Now checking to see if it can run using MSLET instead of PRMSL. --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index 1cfd242eea..cef575d86b 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -60,8 +60,8 @@ TC_DIAG_OUTPUT_TEMPLATE = {date?fmt=%Y} # https://metplus.readthedocs.io/en/latest/Users_Guide/systemconfiguration.html#field-info ### -BOTH_VAR1_NAME = PRMSL -#BOTH_VAR1_NAME = MSLET +#BOTH_VAR1_NAME = PRMSL +BOTH_VAR1_NAME = MSLET BOTH_VAR1_LEVELS = Z0 BOTH_VAR2_NAME = TMP @@ -137,4 +137,4 @@ TC_DIAG_DOMAIN_INFO2_DELTA_RANGE_KM = 2.0 #TC_DIAG_CIRA_DIAG_FLAG = #TC_DIAG_OUTPUT_PREFIX = -LOG_LEVEL=DEBUG \ No newline at end of file +#LOG_LEVEL=DEBUG \ No newline at end of file From cc5831525e9a8998fc064a44e4751648f56d5e39 Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Tue, 11 Jul 2023 14:44:22 -0400 Subject: [PATCH 44/57] #1626: Cleaning up for finalization. --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index cef575d86b..8bd7dc9a9f 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -60,8 +60,7 @@ TC_DIAG_OUTPUT_TEMPLATE = {date?fmt=%Y} # https://metplus.readthedocs.io/en/latest/Users_Guide/systemconfiguration.html#field-info ### -#BOTH_VAR1_NAME = PRMSL -BOTH_VAR1_NAME = MSLET +BOTH_VAR1_NAME = PRMSL BOTH_VAR1_LEVELS = Z0 BOTH_VAR2_NAME = TMP @@ -73,8 +72,7 @@ BOTH_VAR2_LEVELS = P1000, P900, P800, P700, P500, P100 # https://metplus.readthedocs.io/en/latest/Users_Guide/wrappers.html#tcdiag ### -#LOG_TC_DIAG_VERBOSITY = 2 -LOG_TC_DIAG_VERBOSITY = 5 +LOG_TC_DIAG_VERBOSITY = 2 # ToDo: Remove this when finished SCRUB_STAGING_DIR = False From 225a83ecb15ca57c8a1ddc5234e632d6aff68edf Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Tue, 11 Jul 2023 14:44:57 -0400 Subject: [PATCH 45/57] #1626: Removed data staging. --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 3 --- 1 file changed, 3 deletions(-) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index 8bd7dc9a9f..72be3f008f 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -74,9 +74,6 @@ BOTH_VAR2_LEVELS = P1000, P900, P800, P700, P500, P100 LOG_TC_DIAG_VERBOSITY = 2 -# ToDo: Remove this when finished -SCRUB_STAGING_DIR = False - TC_DIAG_CONFIG_FILE = {PARM_BASE}/met_config/TCDiagConfig_wrapped MODEL = GFSO From 4de1c624219b9b5497931e4e82e985fa8117c1cd Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Tue, 11 Jul 2023 14:11:56 -0600 Subject: [PATCH 46/57] add example of complex subset of grib2 data --- docs/Contributors_Guide/add_use_case.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/Contributors_Guide/add_use_case.rst b/docs/Contributors_Guide/add_use_case.rst index b60ee6534a..46f6a1780a 100644 --- a/docs/Contributors_Guide/add_use_case.rst +++ b/docs/Contributors_Guide/add_use_case.rst @@ -326,6 +326,12 @@ file.grib2, run the following command:: wgrib2 file.grib2 | grep TMP | wgrib2 -i file.grib2 -grib_out subset.grib2 +The egrep command can be used for more complex subsetting of grib2 data. +Example: To create a file called subset.grib2 from file.grib2 that contains +PRMSL data and TMP data on 1000, 900, 800, 700, 500, and 100 mb levels:: + + file.grib2 -s | egrep '(:TMP:1000 mb:|:TMP:900 mb:|:TMP:800 mb:|:TMP:700 mb:|:TMP:500 mb:|:TMP:100 mb:|:PRMSL)' | wgrib2 -i file.grib2 -grib subset.grib2 + If the input data is in NetCDF format, the `ncks `_ tool can be used to subset the file(s). From 99cbe4dab1d41a436336d21966450c8fa6528752 Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Tue, 11 Jul 2023 19:41:25 -0400 Subject: [PATCH 47/57] #1626 @georgemccabe: Verifying that the use case works on subsetted data. Corrected a typo in the Contributor's Guide for the complex subsetting example. --- docs/Contributors_Guide/add_use_case.rst | 2 +- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/Contributors_Guide/add_use_case.rst b/docs/Contributors_Guide/add_use_case.rst index 46f6a1780a..a036c6ddea 100644 --- a/docs/Contributors_Guide/add_use_case.rst +++ b/docs/Contributors_Guide/add_use_case.rst @@ -330,7 +330,7 @@ The egrep command can be used for more complex subsetting of grib2 data. Example: To create a file called subset.grib2 from file.grib2 that contains PRMSL data and TMP data on 1000, 900, 800, 700, 500, and 100 mb levels:: - file.grib2 -s | egrep '(:TMP:1000 mb:|:TMP:900 mb:|:TMP:800 mb:|:TMP:700 mb:|:TMP:500 mb:|:TMP:100 mb:|:PRMSL)' | wgrib2 -i file.grib2 -grib subset.grib2 + wgrib2 file.grib2 -s | egrep '(:TMP:1000 mb:|:TMP:900 mb:|:TMP:800 mb:|:TMP:700 mb:|:TMP:500 mb:|:TMP:100 mb:|:PRMSL)' | wgrib2 -i file.grib2 -grib subset.grib2 If the input data is in NetCDF format, the `ncks `_ tool can be used to subset diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index 72be3f008f..1cd3cb312f 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -38,16 +38,16 @@ LEAD_SEQ = 0, 6, 12 ### TC_DIAG_DECK_INPUT_DIR = {INPUT_BASE}/met_test/new/tc_data/adeck -TC_DIAG_DECK_TEMPLATE = aal03{date?fmt=%Y}.dat +TC_DIAG_DECK_TEMPLATE = subset.aal03{date?fmt=%Y}.dat TC_DIAG_INPUT1_DIR = {INPUT_BASE}/met_test/new/model_data/grib2/gfs -TC_DIAG_INPUT1_TEMPLATE = gfs.t12z.pgrb2.0p50.f* +TC_DIAG_INPUT1_TEMPLATE = subset.gfs.t12z.pgrb2.0p50.f* TC_DIAG_INPUT1_DOMAIN = parent TC_DIAG_INPUT1_TECH_ID_LIST = AVNO TC_DIAG_INPUT2_DIR = {INPUT_BASE}/met_test/new/model_data/grib2/gfs -TC_DIAG_INPUT2_TEMPLATE = gfs.t12z.pgrb2.0p50.f* +TC_DIAG_INPUT2_TEMPLATE = subset.gfs.t12z.pgrb2.0p50.f* TC_DIAG_INPUT2_DOMAIN = nest TC_DIAG_INPUT2_TECH_ID_LIST = AVNO From 3d207c7e569dd5c8e511f2b132b17b575ef998af Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 12 Jul 2023 09:51:57 -0600 Subject: [PATCH 48/57] add TCDiag basic use case to automated tests and set it to run to test --- .github/parm/use_case_groups.json | 5 +++++ internal/tests/use_cases/all_use_cases.txt | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/parm/use_case_groups.json b/.github/parm/use_case_groups.json index 23ff852726..5d6aa1b0f7 100644 --- a/.github/parm/use_case_groups.json +++ b/.github/parm/use_case_groups.json @@ -9,6 +9,11 @@ "index_list": "30-58", "run": false }, + { + "category": "met_tool_wrapper", + "index_list": "62", + "run": true + }, { "category": "air_quality_and_comp", "index_list": "0", diff --git a/internal/tests/use_cases/all_use_cases.txt b/internal/tests/use_cases/all_use_cases.txt index a4d4d23afd..cf15709cdf 100644 --- a/internal/tests/use_cases/all_use_cases.txt +++ b/internal/tests/use_cases/all_use_cases.txt @@ -61,7 +61,7 @@ Category: met_tool_wrapper 59::IODA2NC::met_tool_wrapper/IODA2NC/IODA2NC.conf 60::PointStat_python_embedding_obs:: met_tool_wrapper/PointStat/PointStat_python_embedding_obs.conf 61::PlotPointObs:: met_tool_wrapper/PlotPointObs/PlotPointObs.conf -#62::TCDiag:: met_tool_wrapper/TCDiag/TCDiag.conf +62::TCDiag:: met_tool_wrapper/TCDiag/TCDiag.conf Category: air_quality_and_comp 0::EnsembleStat_fcstICAP_obsMODIS_aod::model_applications/air_quality_and_comp/EnsembleStat_fcstICAP_obsMODIS_aod.conf From 781c0852d80c28586ae8922befba8c9c84ec55d9 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 12 Jul 2023 10:23:32 -0600 Subject: [PATCH 49/57] turn off use case group after confirming it works in automated tests --- .github/parm/use_case_groups.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/parm/use_case_groups.json b/.github/parm/use_case_groups.json index 5d6aa1b0f7..4940fd9a06 100644 --- a/.github/parm/use_case_groups.json +++ b/.github/parm/use_case_groups.json @@ -12,7 +12,7 @@ { "category": "met_tool_wrapper", "index_list": "62", - "run": true + "run": false }, { "category": "air_quality_and_comp", From ff909ed4e815f047c0211aeb3aeda3829bb68aee Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 13 Jul 2023 15:49:22 -0600 Subject: [PATCH 50/57] updated use case to include pressure levels that are found in the newly revised input dataset --- parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf index 1cd3cb312f..b489eec5ba 100644 --- a/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf +++ b/parm/use_cases/met_tool_wrapper/TCDiag/TCDiag.conf @@ -64,7 +64,7 @@ BOTH_VAR1_NAME = PRMSL BOTH_VAR1_LEVELS = Z0 BOTH_VAR2_NAME = TMP -BOTH_VAR2_LEVELS = P1000, P900, P800, P700, P500, P100 +BOTH_VAR2_LEVELS = P1000, P925, P850, P700, P500, P400, P300, P250, P200, P150, P100 ### From 54f0aee727b9679be5bbc78078014984dc062a6e Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 13 Jul 2023 15:49:41 -0600 Subject: [PATCH 51/57] turn on new use case to test, ci-skip-unit-tests --- .github/parm/use_case_groups.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/parm/use_case_groups.json b/.github/parm/use_case_groups.json index 4940fd9a06..5d6aa1b0f7 100644 --- a/.github/parm/use_case_groups.json +++ b/.github/parm/use_case_groups.json @@ -12,7 +12,7 @@ { "category": "met_tool_wrapper", "index_list": "62", - "run": false + "run": true }, { "category": "air_quality_and_comp", From cb7678bd9e03b70a52c4b94ca013eee1eeb9f59d Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 13 Jul 2023 16:23:42 -0600 Subject: [PATCH 52/57] turn off use case for PR --- .github/parm/use_case_groups.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/parm/use_case_groups.json b/.github/parm/use_case_groups.json index 5d6aa1b0f7..4940fd9a06 100644 --- a/.github/parm/use_case_groups.json +++ b/.github/parm/use_case_groups.json @@ -12,7 +12,7 @@ { "category": "met_tool_wrapper", "index_list": "62", - "run": true + "run": false }, { "category": "air_quality_and_comp", From c843beb6b856065da29c1c91d58eb2f3fd2f802c Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Thu, 13 Jul 2023 20:20:46 -0400 Subject: [PATCH 53/57] As per #1616, updated the documentation for the basic TCDiag use case to reflect the init time and lead times for this case. Also updated the expected output. --- docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py b/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py index 6dddb13450..c888b804aa 100644 --- a/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py +++ b/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py @@ -79,8 +79,8 @@ # TCDiag is the only tool called in this example. It processes the following # run times: # -# **Init:** 2016-09-29 0000Z -# **Forecast lead:** 141, 144, and 147 hour +# **Init:** 2023-06-20 0000Z +# **Forecast lead:** 0, 6, and 12 hours # ############################################################################## @@ -133,8 +133,8 @@ # Output for this use case will be found in met_tool_wrapper/TCDiag (relative to **OUTPUT_BASE**) # and will contain the following files: # -# * tc_diag_AL142016_fv3_2016092900_cyl_grid_nest.nc -# * tc_diag_AL142016_fv3_2016092900_cyl_grid_parent.nc +# * tc_diag_AL032023_GFSO_2023062012_cyl_grid_nest.nc +# * tc_diag_AL032023_GFSO_2023062012_cyl_grid_parent.nc # ############################################################################## From c21d6af944ec7c6cac191a20d1ad171b9d7d9672 Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Thu, 13 Jul 2023 20:22:52 -0400 Subject: [PATCH 54/57] As per #1626, fixing formatting of the introductory doc block which got split off from the main part. --- docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py b/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py index c888b804aa..7b6f0e379f 100644 --- a/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py +++ b/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py @@ -27,7 +27,6 @@ # a future version of the tc_diag tool will include removal of the model's vortex, # allowing diagnostics to be computed along any arbitrarily defined track.) # - # Novel aspects of this use case: # # This is the first example use case to run the tc_diag tool. From 408bf1eed56ae0de9538abaf0b3411d95f69cfcd Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Thu, 13 Jul 2023 20:29:39 -0400 Subject: [PATCH 55/57] As per #1626, another formatting fix. --- docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py b/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py index 7b6f0e379f..d4ef71d8d5 100644 --- a/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py +++ b/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py @@ -28,10 +28,9 @@ # allowing diagnostics to be computed along any arbitrarily defined track.) # # Novel aspects of this use case: -# -# This is the first example use case to run the tc_diag tool. -# Example of running for a single tropical cyclone forecast case from -# Tropical Storm Bret (2023) using GFS data. +# * This is the first example use case to run the tc_diag tool. +# * Example of running for a single tropical cyclone forecast case from +# Tropical Storm Bret (2023) using GFS data. ############################################################################## # Scientific Objective From 08aefa8c68eef036411884d992ebb0d1adb14ea5 Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Thu, 13 Jul 2023 20:35:47 -0400 Subject: [PATCH 56/57] @georgemccabe, as per #1626, changing the version of MET in the TCDiagConfig_wrapped to 11.1.0. Is this correct? --- parm/met_config/TCDiagConfig_wrapped | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parm/met_config/TCDiagConfig_wrapped b/parm/met_config/TCDiagConfig_wrapped index 43d3708c09..d20be1a55b 100644 --- a/parm/met_config/TCDiagConfig_wrapped +++ b/parm/met_config/TCDiagConfig_wrapped @@ -182,7 +182,7 @@ tmp_dir = "${MET_TMP_DIR}"; //output_prefix = ${METPLUS_OUTPUT_PREFIX} -//version = "V11.0.0"; +//version = "V11.1.0"; //////////////////////////////////////////////////////////////////////////////// From 31043a1f448ebec799fa52fff0d3bca44cde1aee Mon Sep 17 00:00:00 2001 From: Jonathan Vigh Date: Thu, 13 Jul 2023 21:04:11 -0400 Subject: [PATCH 57/57] #1626. I think my previous attempt at a bulleted list for the novel features of the use case broke the documentation build. Trying this mod. --- docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py b/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py index d4ef71d8d5..d525cbc8f8 100644 --- a/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py +++ b/docs/use_cases/met_tool_wrapper/TCDiag/TCDiag.py @@ -28,9 +28,9 @@ # allowing diagnostics to be computed along any arbitrarily defined track.) # # Novel aspects of this use case: -# * This is the first example use case to run the tc_diag tool. -# * Example of running for a single tropical cyclone forecast case from -# Tropical Storm Bret (2023) using GFS data. +# * This is the first example use case to run the tc_diag tool. +# * Example of running for a single tropical cyclone forecast case from +# Tropical Storm Bret (2023) using GFS data. ############################################################################## # Scientific Objective