#!/usr/bin/env python3 import sys import logging import re from pathlib import Path # Variables to check: # VERIF_CASE # info case: # warning case: should match one of the known verif cases # error case: should be string (in quotes), should not be empty def check_VERIF_CASE(VERIF_CASE): if not isinstance(VERIF_CASE, str): sys.exit(f"The provided VERIF_CASE ('{VERIF_CASE}') is not a string." + f" VERIF_CASE must be a string. Check the plotting" + f" configuration file.") ##sys.exit(1) if not VERIF_CASE: sys.exit(f"The provided VERIF_CASE is empty. VERIF_CASE cannot be" + f" empty. Check the plotting configuration file.") ##sys.exit(1) return VERIF_CASE # VERIF_TYPE # info case: # warning case:should match one of the the known verif cases # error case: should be a string(in quotes), shouild not be empty def check_VERIF_TYPE(VERIF_TYPE): if not isinstance(VERIF_TYPE, str): sys.exit(f"The provided VERIF_TYPE ('{VERIF_TYPE}') is not a string." + f" VERIF_TYPE must be a string. Check the plotting" + f" configuration file.") ##sys.exit(1) if not VERIF_TYPE: sys.exit(f"The provided VERIF_TYPE is empty. VERIF_TYPE cannot be" + f" empty. Check the plotting configuration file.") ##sys.exit(1) return VERIF_TYPE # URL_HEADER # info case: whether or not an empty string is provided # warning case: # error case:should be a string (in quotes), should be alphanumeric, should follow file naming conventions def check_URL_HEADER(URL_HEADER): if not isinstance(URL_HEADER, str): sys.exit(f"The provided URL_HEADER ('{URL_HEADER}') is not a string." + f" URL_HEADER must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if re.search(r'[^A-Za-z0-9_\-\\]', URL_HEADER): sys.exit(f"The provided URL_HEADER string ('{URL_HEADER}') contains" + f" invalid characters. URL_HEADER must be made of" + f" alphanumeric characters, hyphen, and/or underscore." + f" Check the plotting configuration file.") #sys.exit(1) if not URL_HEADER: print(f"The provided URL_HEADER is empty. Plot file names will" + f" not include a header.") return URL_HEADER # USH_DIR # info case:whether or not an empty string is provided # warning case: # error case:should be a string, should follow proper directory structure def check_USH_DIR(USH_DIR): if not isinstance(USH_DIR, str): sys.exit(f"The provided USH_DIR ('{USH_DIR}') is not a string." + f" USH_DIR must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if not Path(USH_DIR).exists(): print(f"WARNING: The provided USH_DIR ('{USH_DIR}') does not exist on the" + f" current system.") if not Path(USH_DIR).is_dir(): print(f"WARNING: The provided USH_DIR ('{USH_DIR}') is not a directory.") if not USH_DIR: print(f"The provided USH_DIR is empty. Will look for USH files" + f" in the current working directory.") return USH_DIR # PRUNE_DIR # info case: whether or not an empty string is provided # warning case: # error case: should be a string, should follow proper directory structure def check_PRUNE_DIR(PRUNE_DIR): if not isinstance(PRUNE_DIR, str): sys.exit(f"The provided PRUNE_DIR ('{PRUNE_DIR}') is not a string." + f" PRUNE_DIR must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if not Path(PRUNE_DIR).exists(): print(f"WARNING: The provided PRUNE_DIR ('{PRUNE_DIR}') does not exist on the" + f" current system.") if not Path(PRUNE_DIR).is_dir(): print(f"WARNING: The provided PRUNE_DIR ('{PRUNE_DIR}') is not a directory.") if not PRUNE_DIR: print(f"The provided PRUNE_DIR is empty. Will store pruned stat files" + f" in the current working directory.") return PRUNE_DIR # SAVE_DIR # info case: whether or not an empty string is provided # warning case: # error case: should be a string, should follow proper directory structure def check_SAVE_DIR(SAVE_DIR): if not isinstance(SAVE_DIR, str): sys.exit(f"The provided SAVE_DIR ('{SAVE_DIR}') is not a string." + f" SAVE_DIR must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if not Path(SAVE_DIR).exists(): print(f"WARNING: The provided SAVE_DIR ('{SAVE_DIR}') does not exist on the" + f" current system.") if not Path(SAVE_DIR).is_dir(): print(f"WARNING: The provided SAVE_DIR ('{SAVE_DIR}') is not a directory.") if not SAVE_DIR: print(f"The provided SAVE_DIR is empty. Will store plots" + f" in the current working directory.") return SAVE_DIR # FIX_DIR # info case: whether or not an empty string is provided # warning case: # error case: should be a string, should follow proper directory structure def check_FIX_DIR(FIX_DIR): if not isinstance(FIX_DIR, str): sys.exit(f"The provided FIX_DIR ('{FIX_DIR}') is not a string." + f" FIX_DIR must be a string. Check the plotting" + f" configuration file.") if not Path(FIX_DIR).exists(): print(f"WARNING: The provided FIX_DIR ('{FIX_DIR}') does not exist on the" + f" current system.") if not Path(FIX_DIR).is_dir(): print(f"WARNING: The provided FIX_DIR ('{FIX_DIR}') is not a directory.") if not FIX_DIR: print(f"The provided FIX_DIR is empty.") return FIX_DIR # OUTPUT_BASE_DIR # info case: whether or not an empty string is provided # warning case: # error case:should be a string, should follow proper directory structure def check_OUTPUT_BASE_DIR(OUTPUT_BASE_DIR): if not isinstance(OUTPUT_BASE_DIR, str): sys.exit(f"The provided OUTPUT_BASE_DIR ('{OUTPUT_BASE_DIR}') is not a string." + f" OUTPUT_BASE_DIR must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if not Path(OUTPUT_BASE_DIR).exists(): print(f"WARNING: The provided OUTPUT_BASE_DIR ('{OUTPUT_BASE_DIR}') does not exist on the" + f" current system.") if not Path(OUTPUT_BASE_DIR).is_dir(): print(f"WARNING: The provided OUTPUT_BASE_DIR ('{OUTPUT_BASE_DIR}') is not a directory.") if not OUTPUT_BASE_DIR: print(f"The provided OUTPUT_BASE_DIR is empty. Will look for stat files" + f" in the current working directory.") return OUTPUT_BASE_DIR # LOG_METPLUS # info case: # warning case: # error case: should be a string, should follow proper directory structure, should not be empty def check_LOG_METPLUS(LOG_METPLUS): if not isinstance(LOG_METPLUS, str): sys.exit(f"The provided LOG_METPLUS ('{LOG_METPLUS}') is not a string." + f" LOG_METPLUS must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if not LOG_METPLUS: print(f"WARNING: The provided LOG_METPLUS is empty. The logger will be" + f" the root logger of the hierarchy.") return LOG_METPLUS # LOG_LEVEL # info case: # warning case: whether or not log level is currently supported # error case: should be a string, should match one of the possible log levels def check_LOG_LEVEL(LOG_LEVEL): if not isinstance(LOG_LEVEL, str): sys.exit(f"The provided LOG_LEVEL ('{LOG_LEVEL}') is not a string." + f" LOG_LEVEL must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if str(LOG_LEVEL).upper() not in ["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG", "NOTSET"]: print(f"WARNING: The provided LOG_LEVEL ('{LOG_LEVEL}') may not be" + f" supported by the logger. Consider using one of" + f" 'DEBUG', 'INFO', 'WARNING', 'ERROR', or" + f" 'CRITICAL'.") if str(LOG_LEVEL).upper() not in ["ERROR", "WARNING", "INFO", "DEBUG"]: print(f"WARNING: You provided the following LOG_LEVEL: '{LOG_LEVEL}'." + f" Note that the plotting scripts currently only log at" + f" 'ERROR', 'WARNING', 'INFO' and 'DEBUG' levels.") if not LOG_LEVEL: sys.exit(f"The provided LOG_LEVEL is empty. LOG_LEVEL cannot be" + f" empty. Check the plotting configuration file.") #sys.exit(1) return LOG_LEVEL # MET_VERSION # info case: # warning case: # error case: string be a string, string should contain an integer or a floating point number def check_MET_VERSION(MET_VERSION): if not isinstance(MET_VERSION, str): sys.exit(f"The provided MET_VERSION ('{MET_VERSION}') is not a string." + f" MET_VERSION must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if not re.search(r'^[1-9]\d*(\.\d+)?$', MET_VERSION): sys.exit(f"The provided MET_VERSION ('{MET_VERSION}') is not a" + f" parseable number. Check the plotting configuration" + f" file.") #sys.exit(1) return MET_VERSION # MODEL # info case: # warning case: # error case: should be a string, should be comma-separated or contain no other symbols than letters, numbers, dashes, and underlines def check_MODEL(MODEL): if not isinstance(MODEL, str): sys.exit(f"The provided MODEL ('{MODEL}') is not a string." + f" MODEL must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if not re.search(r'(^[ A-Za-z0-9,\-_]+)$', MODEL): sys.exit(f"The provided MODEL ('{MODEL}') is not valid. MODEL may" + f" contain letters, numbers, hyphens, underscores," + f" commas, and spaces only. Check the plotting" + f" configuration file.") #sys.exit(1) return MODEL # OBTYPE # info case: # warning case: # error case: should be a string, should be comma-separated or contain no other symbols than letters, numbers, dashes, and underlines def check_OBTYPE(OBTYPE): if not isinstance(OBTYPE, str): sys.exit(f"The provided OBTYPE ('{OBTYPE}') is not a string." + f" OBTYPE must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if not re.search(r'(^[ A-Za-z0-9,\-_]+)$', OBTYPE): sys.exit(f"The provided OBTYPE ('{OBTYPE}') is not valid. OBTYPE may" + f" contain letters, numbers, hyphens, underscores," + f" commas, and spaces only. Check the plotting" + f" configuration file.") #sys.exit(1) return OBTYPE # RUN # info case: # warning case: # error case: should be a string, should be comma-separated or contain no other symbols than letters, numbers, dashes, and underlines def check_RUN(RUN): if not isinstance(RUN, str): sys.exit(f"The provided RUN ('{RUN}') is not a string." + f" RUN must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if not re.search(r'(^[ A-Za-z0-9,\-_]+)$', RUN): sys.exit(f"The provided RUN ('{RUN}') is not valid. RUN may" + f" contain letters, numbers, hyphens, underscores," + f" commas, and spaces only. Check the plotting" + f" configuration file.") #sys.exit(1) return RUN # DATE_TYPE # info case: # warning case: # error case: should be a string, should be either INIT or VALID def check_DATE_TYPE(DATE_TYPE): if not isinstance(DATE_TYPE, str): sys.exit(f"The provided DATE_TYPE ('{DATE_TYPE}') is not a string." + f" DATE_TYPE must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if str(DATE_TYPE).upper() not in ['INIT', 'VALID']: sys.exit(f"You provided the following DATE_TYPE: '{DATE_TYPE}'." + f" DATE_TYPE must be either 'INIT' or 'VALID'. Check" + f" the plotting configuration file.") #sys.exit(1) return DATE_TYPE # EVAL_PERIOD # info case: Whether or not a TEST will be used and what that means # warning case: Should be either TEST or a valid EVAL PERIOD # error case: should be a string, should be alphanumeric, def check_EVAL_PERIOD(EVAL_PERIOD): if not isinstance(EVAL_PERIOD, str): sys.exit(f"The provided EVAL_PERIOD ('{EVAL_PERIOD}') is not a string." + f" EVAL_PERIOD must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if re.search(r'[^A-Za-z0-9_\-\\]', EVAL_PERIOD): sys.exit(f"The provided EVAL_PERIOD string ('{EVAL_PERIOD}') contains" + f" invalid characters. EVAL_PERIOD must be made of" + f" alphanumeric characters, hyphen, and/or underscore." + f" Check the plotting configuration file.") #sys.exit(1) if EVAL_PERIOD=="TEST": print(f"Since the EVAL_PERIOD is set to 'TEST', will use a" + f" custom INIT/VALID period.") else: print(f"Since the EVAL_PERIOD is not set to 'TEST', will use a" + f" preset INIT/VALID period (check ush/settings.py for" + f" possible presets).") return EVAL_PERIOD # VALID_BEG # info case: # warning case: # error case: should be a string, if DATE_TYPE="VALID" or plot is valid_hour_average then should contain numbers only, should be YYYYMMDD format only, should be earlier than VALID_END, and cannot be blank def check_VALID_BEG(VALID_BEG, DATE_TYPE, EVAL_PERIOD, plot_type=None): if not isinstance(VALID_BEG, str): sys.exit(f"The provided VALID_BEG ('{VALID_BEG}') is not a string." + f" VALID_BEG must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if ((str(DATE_TYPE).upper() == "VALID" or str(plot_type).lower() == "valid_hour_average") and EVAL_PERIOD == "TEST"): if not VALID_BEG: sys.exit(f"The provided VALID_BEG is empty. Since DATE_TYPE is" + f" '{str(DATE_TYPE).upper()}', plot_type is" + f" '{str(plot_type).lower()}', and EVAL_PERIOD is" + f" '{str(EVAL_PERIOD).upper()}', VALID_BEG cannot be" + f" empty. Check the plotting configuration file.") #sys.exit(1) if not VALID_BEG.isdigit(): sys.exit(f"The provided VALID_BEG ('{VALID_BEG}') contains" + f" non-numeric characters. VALID_BEG may only" + f" contain numeric characters. Check the plotting" + f" configuration file.") #sys.exit(1) if not len(VALID_BEG) == 8: sys.exit(f"The provided VALID_BEG ('{VALID_BEG}') is too short" + f" or too long. VALID_BEG must be a date" + f" in the form of YYYYMMDD. Check the plotting" + f" configuration file.") #sys.exit(1) return VALID_BEG # VALID_END # info case: # warning case: # error case: should be a string, if DATE_TYPE="VALID" or plot is valid_hour_average then should contain numbers only, should be YYYYMMDD format only, should be later than VALID_BEG, and cannot be blank def check_VALID_END(VALID_END, DATE_TYPE, EVAL_PERIOD, plot_type=None): if not isinstance(VALID_END, str): sys.exit(f"The provided VALID_END ('{VALID_END}') is not a string." + f" VALID_END must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if ((str(DATE_TYPE).upper() == "VALID" or str(plot_type).lower() == "valid_hour_average") and EVAL_PERIOD == "TEST"): if not VALID_END: sys.exit(f"The provided VALID_END is empty. Since DATE_TYPE is" + f" '{str(DATE_TYPE).upper()}', plot_type is" + f" '{str(plot_type).lower()}', and EVAL_PERIOD is" + f" '{str(EVAL_PERIOD).upper()}', VALID_END cannot be" + f" empty. Check the plotting configuration file.") #sys.exit(1) if not VALID_END.isdigit(): sys.exit(f"The provided VALID_END ('{VALID_END}') contains" + f" non-numeric characters. VALID_END may only" + f" contain numeric characters. Check the plotting" + f" configuration file.") #sys.exit(1) if not len(VALID_END) == 8: sys.exit(f"The provided VALID_END ('{VALID_END}') is too short" + f" or too long. VALID_END must be a date" + f" in the form of YYYYMMDD. Check the plotting" + f" configuration file.") #sys.exit(1) return VALID_END # INIT_BEG # info case: # warning case: # error case: should be a string, if DATE_TYPE="INIT" then should contain numbers only, should be YYYYMMDD format only, should be earlier than INIT_END, and cannot be blank def check_INIT_BEG(INIT_BEG, DATE_TYPE, EVAL_PERIOD, plot_type=None): if not isinstance(INIT_BEG, str): sys.exit(f"The provided INIT_BEG ('{INIT_BEG}') is not a string." + f" INIT_BEG must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if ((str(DATE_TYPE).upper() == "INIT" or str(plot_type).lower() == "valid_hour_average") and EVAL_PERIOD == "TEST"): if not INIT_BEG: sys.exit(f"The provided INIT_BEG is empty. Since DATE_TYPE is" + f" '{str(DATE_TYPE).upper()}', plot_type is" + f" '{str(plot_type).lower()}', and EVAL_PERIOD is" + f" '{str(EVAL_PERIOD).upper()}', INIT_BEG cannot be" + f" empty. Check the plotting configuration file.") #sys.exit(1) if not INIT_BEG.isdigit(): sys.exit(f"The provided INIT_BEG ('{INIT_BEG}') contains" + f" non-numeric characters. INIT_BEG may only" + f" contain numeric characters. Check the plotting" + f" configuration file.") #sys.exit(1) if not len(INIT_BEG) == 8: sys.exit(f"The provided INIT_BEG ('{INIT_BEG}') is too short" + f" or too long. INIT_BEG must be a date" + f" in the form of YYYYMMDD. Check the plotting" + f" configuration file.") #sys.exit(1) return INIT_BEG # INIT_END # info case: # warning case: # error case: should be a string, if DATE_TYPE="INIT" then should contain numbers only, should be YYYYMMDD format only, should be later than INIT_BEG, and cannot be blank def check_INIT_END(INIT_END, DATE_TYPE, EVAL_PERIOD, plot_type=None): if not isinstance(INIT_END, str): sys.exit(f"The provided INIT_END ('{INIT_END}') is not a string." + f" INIT_END must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if ((str(DATE_TYPE).upper() == "INIT" or str(plot_type).lower() == "valid_hour_average") and EVAL_PERIOD == "TEST"): if not INIT_END: sys.exit(f"The provided INIT_END is empty. Since DATE_TYPE is" + f" '{str(DATE_TYPE).upper()}', plot_type is" + f" '{str(plot_type).lower()}', and EVAL_PERIOD is" + f" '{str(EVAL_PERIOD).upper()}', INIT_END cannot be" + f" empty. Check the plotting configuration file.") #sys.exit(1) if not INIT_END.isdigit(): sys.exit(f"The provided INIT_END ('{INIT_END}') contains" + f" non-numeric characters. INIT_END may only" + f" contain numeric characters. Check the plotting" + f" configuration file.") #sys.exit(1) if not len(INIT_END) == 8: sys.exit(f"The provided INIT_END ('{INIT_END}') is too short" + f" or too long. INIT_END must be a date" + f" in the form of YYYYMMDD. Check the plotting" + f" configuration file.") #sys.exit(1) return INIT_END # FCST_INIT_HOUR # info case: # warning case: # error case: should be a string, if DATE_TYPE="INIT" then should be a comma-separated list of numbers between and including 0 and 23 (leading zeros are fine), no symbols other than numbers, commas, and spaces, should not be blank def check_FCST_INIT_HOUR(FCST_INIT_HOUR, DATE_TYPE, plot_type=None): if not isinstance(FCST_INIT_HOUR, str): sys.exit(f"The provided FCST_INIT_HOUR ('{FCST_INIT_HOUR}') is not a string." + f" FCST_INIT_HOUR must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if (str(DATE_TYPE).upper() == "INIT" or str(plot_type).lower() == "valid_hour_average"): if not FCST_INIT_HOUR: sys.exit(f"The provided FCST_INIT_HOUR is empty. Since DATE_TYPE is" + f" '{str(DATE_TYPE).upper()}' and plot type is" + f" '{str(plot_type).lower()}', FCST_INIT_HOUR cannot be" + f" empty. Check the plotting configuration file.") #sys.exit(1) if not re.search(r'(^[ 0-9,]+)$', FCST_INIT_HOUR): sys.exit(f"The provided FCST_INIT_HOUR ('{FCST_INIT_HOUR}') is" + f" not valid. FCST_INIT_HOUR may contain numbers," + f" commas, and spaces only. Check the plotting" + f" configuration file.") #sys.exit(1) return FCST_INIT_HOUR # FCST_VALID_HOUR # info case: # warning case: # error case: should be a string, if DATE_TYPE="VALID" then should be a comma-separated list of numbers between and including 0 and 23 (leading zeros are fine), no symbols other than numbers, commas, and spaces, should not be blank def check_FCST_VALID_HOUR(FCST_VALID_HOUR, DATE_TYPE, plot_type=None): if not isinstance(FCST_VALID_HOUR, str): sys.exit(f"The provided FCST_VALID_HOUR ('{FCST_VALID_HOUR}') is not a string." + f" FCST_VALID_HOUR must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if (str(DATE_TYPE).upper() == "VALID" or str(plot_type).lower() == "valid_hour_average"): if not FCST_VALID_HOUR: sys.exit(f"The provided FCST_VALID_HOUR is empty. Since DATE_TYPE is" + f" '{str(DATE_TYPE).upper()}' and plot type is" + f" '{str(plot_type).lower()}', FCST_VALID_HOUR cannot be" + f" empty. Check the plotting configuration file.") #sys.exit(1) if not re.search(r'(^[ 0-9,]+)$', FCST_VALID_HOUR): sys.exit(f"The provided FCST_VALID_HOUR ('{FCST_VALID_HOUR}') is" + f" not valid. FCST_VALID_HOUR may contain numbers," + f" commas, and spaces only. Check the plotting" + f" configuration file.") #sys.exit(1) return FCST_VALID_HOUR # FCST_LEVEL # info case: # warning case: should be a valid level (start with a valid letter) # error case: should be a string, should not be blank def check_FCST_LEVEL(FCST_LEVEL): if not isinstance(FCST_LEVEL, str): sys.exit(f"The provided FCST_LEVEL ('{FCST_LEVEL}') is not a string." + f" FCST_LEVEL must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if not FCST_LEVEL: sys.exit(f"The provided FCST_LEVEL is empty. FCST_LEVEL cannot be" + f" empty. Check the plotting configuration file.") #sys.exit(1) return FCST_LEVEL # OBS_LEVEL # info case: whether or not OBS_LEVEL matches FCST_LEVEL # warning case: should be a valid level (start with a valid letter) # error case: should be a string, should not be blank def check_OBS_LEVEL(OBS_LEVEL): if not isinstance(OBS_LEVEL, str): sys.exit(f"The provided OBS_LEVEL ('{OBS_LEVEL}') is not a string." + f" OBS_LEVEL must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if not OBS_LEVEL: sys.exit(f"The provided OBS_LEVEL is empty. OBS_LEVEL cannot be" + f" empty. Check the plotting configuration file.") #sys.exit(1) return OBS_LEVEL # var_name # info case: # warning case: # error case: should be a string, should not be blank def check_var_name(var_name): if not isinstance(var_name, str): sys.exit(f"The provided var_name ('{var_name}') is not a string." + f" var_name must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if not var_name: sys.exit(f"The provided var_name is empty. var_name cannot be" + f" empty. Check the plotting configuration file.") #sys.exit(1) if re.search(r'[^ A-Za-z0-9,_\-]', var_name): sys.exit(f"The provided var_name string ('{var_name}') contains" + f" invalid characters. var_name must be made of" + f" alphanumeric characters, hyphen, underscore, commas" + f" and/or spaces only. Check the plotting configuration" + f" file.") #sys.exit(1) return var_name # VX_MASK_LIST # info case: # warning case: # error case: should be a string, should not be blank def check_VX_MASK_LIST(VX_MASK_LIST): if not isinstance(VX_MASK_LIST, str): sys.exit(f"The provided VX_MASK_LIST ('{VX_MASK_LIST}') is not a string." + f" VX_MASK_LIST must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if not VX_MASK_LIST: sys.exit(f"The provided VX_MASK_LIST is empty. VX_MASK_LIST cannot be" + f" empty. Check the plotting configuration file.") #sys.exit(1) if re.search(r'[^ A-Za-z0-9,_\-]', VX_MASK_LIST): sys.exit(f"The provided VX_MASK_LIST string ('{VX_MASK_LIST}') contains" + f" invalid characters. VX_MASK_LIST must be made of" + f" alphanumeric characters, hyphen, underscore, commas" + f" and/or spaces only. Check the plotting configuration" + f" file.") #sys.exit(1) return VX_MASK_LIST # FCST_LEAD # info case: # warning case: # error case: should be a string, should not be blank, should be a comma-separated list of positive numbers def check_FCST_LEAD(FCST_LEAD): if not isinstance(FCST_LEAD, str): sys.exit(f"The provided FCST_LEAD ('{FCST_LEAD}') is not a string." + f" FCST_LEAD must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if not FCST_LEAD: sys.exit(f"The provided FCST_LEAD is empty. FCST_LEAD cannot be" + f" empty. Check the plotting configuration file.") #sys.exit(1) if re.search(r'[^ 0-9,]', FCST_LEAD): sys.exit(f"The provided FCST_LEAD string ('{FCST_LEAD}') contains" + f" invalid characters. FCST_LEAD must be made of" + f" numerics, commas and/or spaces only. Check the" + f" plotting configuration file.") #sys.exit(1) return FCST_LEAD # LINE_TYPE # info case: # warning case: should matcha known line type # error case: should be a string, should not be blank def check_LINE_TYPE(LINE_TYPE): if not isinstance(LINE_TYPE, str): sys.exit(f"The provided LINE_TYPE ('{LINE_TYPE}') is not a string." + f" LINE_TYPE must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if not LINE_TYPE: sys.exit(f"The provided LINE_TYPE is empty. LINE_TYPE cannot be" + f" empty. Check the plotting configuration file.") #sys.exit(1) if re.search(r'[^ A-Za-z0-9]', LINE_TYPE): sys.exit(f"The provided LINE_TYPE string ('{LINE_TYPE}') contains" + f" invalid characters. LINE_TYPE must be made of" + f" alphanumeric characters only. Check the plotting" + f" configuration file.") #sys.exit(1) return LINE_TYPE # INTERP # info case: # warning case: should match a known interp # error case: should be a string, should not be blank def check_INTERP(INTERP): if not isinstance(INTERP, str): sys.exit(f"The provided INTERP ('{INTERP}') is not a string." + f" INTERP must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if not INTERP: sys.exit(f"The provided INTERP is empty. INTERP cannot be" + f" empty. Check the plotting configuration file.") #sys.exit(1) if re.search(r'[^A-Za-z0-9_\-]', INTERP): sys.exit(f"The provided INTERP string ('{INTERP}') contains" + f" invalid characters. INTERP must be made of" + f" alphanumeric characters, hyphens, and/or underscores" + f" only. Check the plotting configuration file.") #sys.exit(1) return INTERP # FCST_THRESH # info case: # warning case: # error case: should be a string, if line type is CTC, MCTC, PCT, NBRCTC then should not be blank, should contain comma-separated list of symbols and numbers, symbols should precede numbers, symbols should be either >,>=,<,<=,==,!= def check_FCST_THRESH(FCST_THRESH, LINE_TYPE): if not isinstance(FCST_THRESH, str): sys.exit(f"The provided FCST_THRESH ('{FCST_THRESH}') is not a" + f" string. FCST_THRESH must be a string. Check the" + f" plotting configuration file.") #sys.exit(1) if str(LINE_TYPE).upper() in ['CTC','MCTC','PCT','NBRCTC']: if not FCST_THRESH: sys.exit(f"The provided FCST_THRESH is empty. Since the" + f" provided line type is '{LINE_TYPE}', FCST_THRESH" + f" cannot be empty. Check the plotting" + f" configuration file.") #sys.exit(1) if re.search(r'[^A-Za-z0-9<>=.,! /-]', FCST_THRESH): sys.exit(f"The provided FCST_THRESH string ('{FCST_THRESH}') contains" + f" invalid characters. FCST_THRESH must be made of" + f" alphanumeric characters, comparison operators," + f" periods, hyphens, commas and/or spaces only. Check the" + f" plotting configuration file.") #sys.exit(1) if re.search(r'^((?![<=!>]).)*$', FCST_THRESH): sys.exit(f"The provided FCST_THRESH string ('{FCST_THRESH}')" + f" does not contain a valid comparison operator" + f" (<,>,<=,>=,!=,==). FCST_THRESH must contain a" + f" valid comparison operator. Check the plotting" + f" configuration file.") #sys.exit(1) if re.search(r'^((?![0-9]).)*$', FCST_THRESH): sys.exit(f"The provided FCST_THRESH string ('{FCST_THRESH}')" + f" contains no numerics (digits 0-9). FCST_THRESH" + f" must contain an integer or decimal in order to" + f" be valid. Check the plotting configuration" + f" file.") #sys.exit(1) return FCST_THRESH # OBS_THRESH # info case: # warning case: whether or not it matches FCST_THRESH # error case: should be a string, if line type is CTC, MCTC, PCT, NBRCTC then should not be blank, should contain comma-separated list of symbols and numbers, symbols should precede numbers, symbols should be either >,>=,<,<=,==,!= def check_OBS_THRESH(OBS_THRESH, FCST_THRESH, LINE_TYPE): if not isinstance(OBS_THRESH, str): sys.exit(f"The provided OBS_THRESH ('{OBS_THRESH}') is not a" + f" string. OBS_THRESH must be a string. Check the" + f" plotting configuration file.") #sys.exit(1) if str(LINE_TYPE).upper() in ['CTC','MCTC','PCT','NBRCTC']: if not OBS_THRESH: sys.exit(f"The provided OBS_THRESH is empty. Since the" + f" provided line type is '{LINE_TYPE}', OBS_THRESH" + f" cannot be empty. Check the plotting" + f" configuration file.") #sys.exit(1) if re.search(r'[^A-Za-z0-9<>=.,! /-]', OBS_THRESH): sys.exit(f"The provided OBS_THRESH string ('{OBS_THRESH}') contains" + f" invalid characters. OBS_THRESH must be made of" + f" alphanumeric characters, comparison operators," + f" periods, hyphens, commas and/or spaces only. Check the" + f" plotting configuration file.") #sys.exit(1) if re.search(r'^((?![<=!>]).)*$', OBS_THRESH): sys.exit(f"The provided OBS_THRESH string ('{OBS_THRESH}')" + f" does not contain a valid comparison operator" + f" (<,>,<=,>=,!=,==). OBS_THRESH must contain a" + f" valid comparison operator. Check the plotting" + f" configuration file.") #sys.exit(1) if re.search(r'^((?![0-9]).)*$', OBS_THRESH): sys.exit(f"The provided OBS_THRESH string ('{OBS_THRESH}')" + f" contains no numerics (digits 0-9). OBS_THRESH" + f" must contain an integer or decimal in order to" + f" be valid. Check the plotting configuration" + f" file.") #sys.exit(1) if (OBS_THRESH.replace(' ','') != FCST_THRESH.replace(' ','') or len(re.split(r'[\s,]+', OBS_THRESH)) != len(re.split(r'[\s,]+', FCST_THRESH))): print(f"WARNING: The provided OBS_THRESH string ('{OBS_THRESH}')" + f" is not equivalent to the provided FCST_THRESH" + f" string ('{FCST_THRESH}').") return OBS_THRESH # STATS # info case: # warning case: # error case: should be a string, should not be blank, def check_STATS(STATS): if not isinstance(STATS, str): sys.exit(f"The provided STATS ('{STATS}') is not a string." + f" STATS must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if not STATS: sys.exit(f"The provided STATS is empty. STATS cannot be" + f" empty. Check the plotting configuration file.") #sys.exit(1) if re.search(r'[^ A-Za-z0-9,_\-]', STATS): sys.exit(f"The provided STATS string ('{STATS}') contains" + f" invalid characters. STATS must be made of" + f" alphanumeric characters, hyphen, underscore, commas" + f" and/or spaces only. Check the plotting configuration" + f" file.") #sys.exit(1) return STATS # CONFIDENCE_INTERVALS # info case: # warning case: should not be blank # error case: should be a string def check_CONFIDENCE_INTERVALS(CONFIDENCE_INTERVALS): if not isinstance(CONFIDENCE_INTERVALS, str): sys.exit(f"The provided CONFIDENCE_INTERVALS ('{CONFIDENCE_INTERVALS}') is not a string." + f" CONFIDENCE_INTERVALS must be a string. Check the plotting" + f" configuration file.") #sys.exit(1) if not CONFIDENCE_INTERVALS: print(f"WARNING: The provided CONFIDENCE_INTERVALS is empty." + f" Confidence intervals will not be plotted. Set to" + f" 'True' if confidence intervals should be plotted.") return CONFIDENCE_INTERVALS