Ejemplo n.º 1
0
 def test_add_recipe_file(self, core_ini, recipes_ini):
     """
     Builds a master config from the files, add a recipe file, check that the recipe name is in the list
     """
     # Build a master config file using multiple files
     mcfg = MasterConfig(path=core_ini)
     mcfg.cfg = mcfg.add_files([recipes_ini])
     assert 'topo_basic_recipe' in [r.name for r in mcfg.recipes]
Ejemplo n.º 2
0
    def parseReport(self):
        """
        Parse the options related to reporting
        """
        # get all relevant options
        snowav_mcfg = MasterConfig(modules='snowav')
        self.sec_snowav = snowav_mcfg.cfg.keys()
        # make reporting directory
        self.path_report_o = os.path.join(self.path_wy, 'reports')
        self.path_report_i = os.path.join(
            self.path_report_o, 'report_{}'.format(self.folder_date_stamp))
        if not os.path.exists(self.path_report_i):
            os.makedirs(self.path_report_i)

        # fill in some of the config options
        self.config['report']['rep_path'] = self.path_report_i
        self.config['snowav system']['save_path'] = self.path_report_i
        self.config['snowav system']['wy'] = self.wy
        self.config['runs']['run_dirs'] = [self.pathro]
        # create updated config for report
        self.report_config = os.path.join(self.path_report_o, 'snowav_cfg.ini')
        #generate_config(self.ucfg, self.report_config)

        ##### new stuff
        # Write out config file to run smrf
        # make copy and delete only awsm sections
        snowav_cfg = copy.deepcopy(self.ucfg)
        for key in self.ucfg.cfg.keys():
            if key in self.sec_awsm or key in self.sec_smrf:
                del snowav_cfg.cfg[key]

        self.tmp_log.append('Writing the config file for snowav')
        generate_config(snowav_cfg, self.report_config)
Ejemplo n.º 3
0
 def test_mcfg_instantiate(self, mcfg_kwargs):
     """
     Attempt to instantiate a master config with different kwargs
     """
     try:
         MasterConfig(**mcfg_kwargs)
         assert True
     except BaseException:
         assert False
Ejemplo n.º 4
0
    def setUpClass(self):
        """
        Create some key structures for testing
        """
        tests_p = os.path.join(os.path.dirname(inicheck.__file__),'../tests')
        self.mcfg = MasterConfig(path=os.path.join(tests_p,
                                    'test_configs/master.ini'))

        self.ucfg = UserConfig(os.path.join(tests_p,"test_configs/base_cfg.ini"),
                               mcfg=self.mcfg)
Ejemplo n.º 5
0
 def test_valid_syntax(self):
     """
     Test we can detect valid syntax
     """
     base = os.path.dirname(__file__)
     master = os.path.join(base, 'test_configs/CoreConfig.ini')
     recipes = os.path.join(base, 'test_configs/recipes.ini')
     mcfg = MasterConfig(path=[master, recipes])
     cf = os.path.join(base, 'test_configs/changelog.ini')
     try:
         c = ChangeLog(paths=cf, mcfg=mcfg)
         assert True
     except Exception as e:
         assert False
Ejemplo n.º 6
0
    def read_config_file(self, config_file):
        """
        Reads in the user's config file and checks

        Args:
            config_file: either a path or a UserConfig instance
        """

        # read the config file and store
        if isinstance(config_file, str):
            if not os.path.isfile(config_file):
                raise Exception(
                    'Configuration file does not exist --> {}'.format(
                        config_file))

            # Get the master config file
            mcfg_dir = os.path.abspath(os.path.dirname(__file__))
            master_config = os.path.join(mcfg_dir, self.CORE_CONFIG)
            mcfg = MasterConfig(path=master_config)

            # user config file
            ucfg = get_user_config(config_file, mcfg=mcfg)

        elif isinstance(config_file, UserConfig):
            ucfg = config_file
            config_file = config_file.filename

        else:
            raise Exception('Config passed to PySnobal is neither file '
                            'name or UserConfig instance')

        # Check the config file
        warnings, errors = check_config(ucfg)
        print_config_report(warnings, errors)
        self.ucfg = ucfg
        self.config = self.ucfg.cfg

        # Exit Pysnobal if config file has errors
        if len(errors) > 0:
            print("Errors in the config file. See configuration"
                  " status report above.")
            sys.exit()
Ejemplo n.º 7
0
    def read_config(self, config):
        if isinstance(config, str):
            if not os.path.isfile(config):
                raise Exception('Configuration file does not exist --> {}'
                                .format(config))
            configFile = config

            try:
                combined_mcfg = MasterConfig(modules=['smrf', 'awsm'])

                # Read in the original users config
                self.ucfg = get_user_config(configFile, mcfg=combined_mcfg)
                self.configFile = configFile

            except UnicodeDecodeError as e:
                print(e)
                raise Exception(('The configuration file is not encoded in '
                                 'UTF-8, please change and retry'))

        elif isinstance(config, UserConfig):
            self.ucfg = config

        else:
            raise Exception("""Config passed to AWSM is neither file """
                            """name nor UserConfig instance""")

        warnings, errors = check_config(self.ucfg)

        if len(errors) > 0:
            print_config_report(warnings, errors)
            print("Errors in the config file. "
                  "See configuration status report above.")
            sys.exit()
        elif len(warnings) > 0:
            print_config_report(warnings, errors)

        self.config = self.ucfg.cfg
Ejemplo n.º 8
0
    def __init__(self, config):
        """
        Initialize the model, read config file, start and end date, and logging
        Args:
            config: string path to the config file or inicheck UserConfig instance
        """
        # read the config file and store
        awsm_mcfg = MasterConfig(modules='awsm')
        smrf_mcfg = MasterConfig(modules='smrf')

        if isinstance(config, str):
            if not os.path.isfile(config):
                raise Exception('Configuration file does not exist --> {}'
                                .format(config))
            configFile = config

            try:
                combined_mcfg = MasterConfig(modules=['smrf', 'awsm'])

                # Read in the original users config
                self.ucfg = get_user_config(configFile, mcfg=combined_mcfg)
                self.configFile = configFile

            except UnicodeDecodeError as e:
                print(e)
                raise Exception(('The configuration file is not encoded in '
                                 'UTF-8, please change and retry'))

        elif isinstance(config, UserConfig):
            self.ucfg = config
            configFile = ''

        else:
            raise Exception(
                'Config passed to AWSM is neither file name nor UserConfig instance')

        # get the git version
        self.gitVersion = awsm_utils.getgitinfo()

        # create blank log and error log because logger is not initialized yet
        self.tmp_log = []
        self.tmp_err = []
        self.tmp_warn = []

        # Check the user config file for errors and report issues if any
        self.tmp_log.append("Checking config file for issues...")
        warnings, errors = check_config(self.ucfg)
        print_config_report(warnings, errors)

        self.config = self.ucfg.cfg

        # Exit AWSM if config file has errors
        if len(errors) > 0:
            print("Errors in the config file. "
                  "See configuration status report above.")
            # sys.exit()

        # ################## Decide which modules to run #####################
        self.do_smrf = self.config['awsm master']['run_smrf']
        #self.do_isnobal = self.config['awsm master']['run_isnobal']
        self.model_type = self.config['awsm master']['model_type']
        # self.do_smrf_ipysnobal = \
        #     self.config['awsm master']['run_smrf_ipysnobal']
        # self.do_ipysnobal = self.config['awsm master']['run_ipysnobal']
        self.do_forecast = False
        if 'gridded' in self.config and self.do_smrf:
            self.do_forecast = self.config['gridded']['hrrr_forecast_flag']

            # WARNING: The value here is inferred in SMRF.data.loadGrid. A
            # change here requires a change there
            self.n_forecast_hours = 18

        # Options for converting files
        self.do_make_in = self.config['awsm master']['make_in']
        self.do_make_nc = self.config['awsm master']['make_nc']
        # do report?
        # self.do_report = self.config['awsm master']['do_report']
        self.snowav_config = self.config['awsm master']['snowav_config']

        # options for masking isnobal
        self.mask_isnobal = self.config['awsm master']['mask_isnobal']

        # prompt for making directories
        self.prompt_dirs = self.config['awsm master']['prompt_dirs']

        # store smrf version if running smrf
        self.smrf_version = smrf.__version__

        # ################ Time information ##################
        self.start_date = pd.to_datetime(self.config['time']['start_date'])
        self.end_date = pd.to_datetime(self.config['time']['end_date'])
        self.time_step = self.config['time']['time_step']
        self.tmz = self.config['time']['time_zone']
        self.tzinfo = pytz.timezone(self.config['time']['time_zone'])
        # date to use for finding wy
        tmp_date = self.start_date.replace(tzinfo=self.tzinfo)
        tmp_end_date = self.end_date.replace(tzinfo=self.tzinfo)

        # find water year hour of start and end date
        self.start_wyhr = int(utils.water_day(tmp_date)[0]*24)
        self.end_wyhr = int(utils.water_day(tmp_end_date)[0]*24)

        # find start of water year
        tmpwy = utils.water_day(tmp_date)[1] - 1
        self.wy_start = pd.to_datetime('{:d}-10-01'.format(tmpwy))

        # ################ Store some paths from config file ##################
        # path to the base drive (i.e. /data/blizzard)
        if self.config['paths']['path_dr'] is not None:
            self.path_dr = os.path.abspath(self.config['paths']['path_dr'])
        else:
            print('No base path to drive given. Exiting now!')
            sys.exit()

        # name of your basin (i.e. Tuolumne)
        self.basin = self.config['paths']['basin']
        # water year of run
        self.wy = utils.water_day(tmp_date)[1]
        # if the run is operational or not
        self.isops = self.config['paths']['isops']
        # name of project if not an operational run
        self.proj = self.config['paths']['proj']
        # check for project description
        self.desc = self.config['paths']['desc']
        # find style for folder date stamp
        self.folder_date_style = self.config['paths']['folder_date_style']

        # setting to output in seperate daily folders
        self.daily_folders = self.config['awsm system']['daily_folders']
        if self.daily_folders and not self.run_smrf_ipysnobal:
            raise ValueError('Cannot run daily_folders with anything other'
                             ' than run_smrf_ipysnobal')

        if self.do_forecast:
            self.tmp_log.append('Forecasting set to True')

            # self.fp_forecastdata = self.config['gridded']['wrf_file']
            # if self.fp_forecastdata is None:
            #     self.tmp_err.append('Forecast set to true, '
            #                         'but no grid file given')
            #     print("Errors in the config file. See configuration "
            #           "status report above.")
            #     print(self.tmp_err)
            #     sys.exit()

            if self.config['system']['threading']:
                # Can't run threaded smrf if running forecast_data
                self.tmp_err.append('Cannot run SMRF threaded with'
                                    ' gridded input data')
                print(self.tmp_err)
                sys.exit()

        # Time step mass thresholds for iSnobal
        self.mass_thresh = []
        self.mass_thresh.append(self.config['grid']['thresh_normal'])
        self.mass_thresh.append(self.config['grid']['thresh_medium'])
        self.mass_thresh.append(self.config['grid']['thresh_small'])

        # threads for running iSnobal
        self.ithreads = self.config['awsm system']['ithreads']
        # how often to output form iSnobal
        self.output_freq = self.config['awsm system']['output_frequency']
        # number of timesteps to run if ou don't want to run the whole thing
        self.run_for_nsteps = self.config['awsm system']['run_for_nsteps']
        # pysnobal output variables
        self.pysnobal_output_vars = self.config['awsm system']['variables']
        self.pysnobal_output_vars = [wrd.lower()
                                     for wrd in self.pysnobal_output_vars]
        # snow and emname
        self.snow_name = self.config['awsm system']['snow_name']
        self.em_name = self.config['awsm system']['em_name']

        # options for restarting iSnobal
        self.restart_crash = False
        if self.config['isnobal restart']['restart_crash']:
            self.restart_crash = True
            # self.new_init = self.config['isnobal restart']['new_init']
            self.depth_thresh = self.config['isnobal restart']['depth_thresh']
            self.restart_hr = \
                int(self.config['isnobal restart']['wyh_restart_output'])
            self.restart_folder = self.config['isnobal restart']['output_folders']

        # iSnobal active layer
        self.active_layer = self.config['grid']['active_layer']

        # if we are going to run ipysnobal with smrf
        if self.model_type in ['ipysnobal', 'smrf_ipysnobal']:
            self.ipy_threads = self.ithreads
            self.ipy_init_type = \
                self.config['files']['init_type']
            self.forcing_data_type = \
                self.config['ipysnobal']['forcing_data_type']

        # parameters needed for restart procedure
        self.restart_run = False
        if self.config['isnobal restart']['restart_crash']:
            self.restart_run = True
            # find restart hour datetime
            reset_offset = pd.to_timedelta(self.restart_hr, unit='h')
            # set a new start date for this run
            self.restart_date = self.wy_start + reset_offset
            self.tmp_log.append('Restart date is {}'.format(self.start_date))

        # read in update depth parameters
        self.update_depth = False
        if 'update depth' in self.config:
            self.update_depth = self.config['update depth']['update']
        if self.update_depth:
            self.update_file = self.config['update depth']['update_file']
            self.update_buffer = self.config['update depth']['buffer']
            self.flight_numbers = self.config['update depth']['flight_numbers']
            # if flights to use is not list, make it a list
            if self.flight_numbers is not None:
                if not isinstance(self.flight_numbers, list):
                    self.flight_numbers = [self.flight_numbers]

        # list of sections releated to AWSM
        # These will be removed for smrf config
        self.sec_awsm = awsm_mcfg.cfg.keys()
        self.sec_smrf = smrf_mcfg.cfg.keys()

        # Make rigid directory structure
        self.mk_directories()

        # ################ Topo data for iSnobal ##################
        # get topo stats
        self.csys = self.config['grid']['csys'].upper()
        self.nbits = int(self.config['grid']['nbits'])
        self.soil_temp = self.config['soil_temp']['temp']
        # get topo class
        self.topo = mytopo(self.config['topo'], self.mask_isnobal,
                           self.model_type, self.csys, self.pathdd)

        # ################ Generate config backup ##################
        # if self.config['output']['input_backup']:
        # set location for backup and output backup of awsm sections
        config_backup_location = \
            os.path.join(self.pathdd, 'awsm_config_backup.ini')
        generate_config(self.ucfg, config_backup_location)

        # create log now that directory structure is done
        self.createLog()

        # if we have a model, initialize it
        if self.model_type is not None:
            self.myinit = modelInit(self._logger, self.config, self.topo,
                                    self.start_wyhr, self.pathro, self.pathrr,
                                    self.pathinit, self.wy_start)
Ejemplo n.º 9
0
    def __init__(self, core_config, config_file, basin=None):
        """Read in docker-airflow config. """

        mcfg = MasterConfig(path=core_config)
        ucfg = get_user_config(config_file, mcfg=mcfg)
        ucfg.apply_recipes()
        ucfg = cast_all_variables(ucfg, ucfg.mcfg)

        warnings, errors = check_config(ucfg)
        if errors != [] or warnings != []:
            print_config_report(warnings, errors)

        # from basin_arguments section
        self.args = {
            "owner":
            ucfg.cfg['basin_arguments']['owner'],
            "depends_on_past":
            ucfg.cfg['basin_arguments']['depends_on_past'],
            "start_date":
            ucfg.cfg['basin_arguments']['start_date'],
            "email":
            ucfg.cfg['basin_arguments']['email'],
            "email_on_failure":
            ucfg.cfg['basin_arguments']['email_on_failure'],
            "email_on_retry":
            ucfg.cfg['basin_arguments']['email_on_retry'],
            "retries":
            ucfg.cfg['basin_arguments']['retries'],
            "retry_delay":
            timedelta(seconds=ucfg.cfg['basin_arguments']['retry_delay'])
        }

        self.snowav_args = {
            "owner":
            ucfg.cfg['snowav_arguments']['owner'],
            "depends_on_past":
            ucfg.cfg['snowav_arguments']['depends_on_past'],
            "start_date":
            ucfg.cfg['snowav_arguments']['start_date'],
            "email":
            ucfg.cfg['snowav_arguments']['email'],
            "email_on_failure":
            ucfg.cfg['snowav_arguments']['email_on_failure'],
            "email_on_retry":
            ucfg.cfg['snowav_arguments']['email_on_retry'],
            "retries":
            ucfg.cfg['snowav_arguments']['retries'],
            "retry_delay":
            timedelta(seconds=ucfg.cfg['snowav_arguments']['retry_delay'])
        }

        # settings
        aimage = ucfg.cfg['settings']['awsm_image']
        atag = ucfg.cfg['settings']['awsm_tag']
        kimage = ucfg.cfg['settings']['katana_image']
        ktag = ucfg.cfg['settings']['katana_tag']
        simage = ucfg.cfg['settings']['snowav_image']
        stag = ucfg.cfg['settings']['snowav_tag']

        self.settings = {
            "awsm_image": aimage + ':' + atag,
            "katana_image": kimage + ':' + ktag,
            "forecast_path": ucfg.cfg['settings']['forecast_path'],
            "geojson": ucfg.cfg['settings']['geojson'],
            "docker_call_backup": ucfg.cfg['settings']['docker_call_backup'],
            "windninja_nthreads": ucfg.cfg['settings']['windninja_nthreads'],
            "katana_zone_letter": ucfg.cfg['settings']['katana_zone_letter'],
            "katana_zone_number": ucfg.cfg['settings']['katana_zone_number'],
            "wy": ucfg.cfg['settings']['wy'],
            "backup_path": ucfg.cfg['settings']['backup_path'],
            "snowav_image": simage + ':' + stag
        }

        # basin sections
        if basin is not None:
            self.basin_settings = {
                "basin": ucfg.cfg[basin]['basin'],
                "base_path": ucfg.cfg[basin]['base_path'],
                "awsm_config": ucfg.cfg[basin]['awsm_config'],
                "retry_awsm_config": ucfg.cfg[basin]['retry_awsm_config'],
                "snowav_config": ucfg.cfg[basin]['snowav_config'],
                "katana_pixel": ucfg.cfg[basin]['katana_pixel'],
                "awsm_path": ucfg.cfg[basin]['awsm_path'],
                "topo_file": ucfg.cfg[basin]['topo_file'],
                "results_path": ucfg.cfg[basin]['results_path']
            }
Ejemplo n.º 10
0
def full_mcfg(master_ini):
    return MasterConfig(path=master_ini)
Ejemplo n.º 11
0
def basic_mcfg(test_config_dir, ):
    """
    Master config fixture to be used with the basic config fixture
    """
    return MasterConfig(path=join(test_config_dir, 'master.ini'))
Ejemplo n.º 12
0
 def smrf_config_sections(self):
     return MasterConfig(modules='smrf').cfg.keys()
Ejemplo n.º 13
0
 def awsm_config_sections(self):
     return MasterConfig(modules='awsm').cfg.keys()
Ejemplo n.º 14
0
 def test_exception_on_no_files(self):
     """
     This tests that a master config when attempted to instantiate without a module or a path throws an exception
     """
     with pytest.raises(ValueError):
         MasterConfig()
Ejemplo n.º 15
0
def get_profile_defaults(section, core_config):
    m = MasterConfig(core_config)
    defaults = {}
    for name, obj in m.cfg[section].items():
        defaults[name] = obj.default
    return defaults
Ejemplo n.º 16
0
    def __init__(self, config_file, awsm=None, end_date=None):

        print('Reading {} and loading files...'.format(config_file))

        self.config_file = config_file
        snowav_mcfg = MasterConfig(modules='snowav')
        ucfg = get_user_config(self.config_file, mcfg=snowav_mcfg)
        ucfg.apply_recipes()
        ucfg = cast_all_variables(ucfg, ucfg.mcfg)
        self.snowav_path = get_snowav_path()

        warnings, errors = check_config(ucfg)
        if errors != [] or warnings != []:
            print_config_report(warnings, errors)

        self.tmp_log = []
        self.tmp_err = []
        self.tmp_warn = []
        self.proc_time_start = datetime.now()

        ####################################################
        #            snowav                                #
        ####################################################
        self.loglevel = ucfg.cfg['snowav']['log_level'].upper()
        self.log_to_file = ucfg.cfg['snowav']['log_to_file']
        self.save_path = ucfg.cfg['snowav']['save_path']
        self.units = ucfg.cfg['snowav']['units']
        self.elev_bins = ucfg.cfg['snowav']['elev_bins']
        self.directory = ucfg.cfg['snowav']['directory']
        self.dempath = ucfg.cfg['snowav']['dempath']
        self.run_name = ucfg.cfg['snowav']['run_name']
        self.plotorder = ucfg.cfg['snowav']['masks']
        self.plotlabels = ucfg.cfg['snowav']['plotlabels']
        self.report_only = ucfg.cfg['snowav']['report_only']

        ####################################################
        #           run                                    #
        ####################################################
        self.dplcs = ucfg.cfg['run']['decimals']
        self.start_date = ucfg.cfg['run']['start_date']
        self.end_date = ucfg.cfg['run']['end_date']

        if end_date is not None:
            self.end_date = end_date
            self.tmp_log.append(' Overriding config end_date with '
                                '{} given with snowav call'.format(end_date))

            if self.end_date <= self.start_date:
                raise Exception(
                    'end_date {} earlier than start_date {}'.format(
                        self.end_date, self.start_date))

        if self.start_date is not None and self.end_date is not None:
            self.start_date = self.start_date
            self.end_date = self.end_date

            if self.start_date >= self.end_date:
                self.tmp_log.append(' Error: [run] start_date >= end_date')
                raise Exception('[run] start_date >= [run] end_date')

        else:
            self.tmp_log.append(' [run] start_date and/or end_date was not '
                                'defined in config file, will be assigned '
                                'by available dates in directory')

        self.all_subdirs = ucfg.cfg['run']['all_subdirs']

        if (ucfg.cfg['run']['directory'] is None) and (awsm is not None):
            if self.all_subdirs is True:
                self.run_dirs = ([
                    awsm.pathr + s for s in os.listdir(awsm.pathr)
                    if (os.path.isdir(awsm.pathr + s))
                ])
            else:
                self.run_dirs = awsm.pathr
                if type(self.run_dirs) != list:
                    self.run_dirs = [self.run_dirs]

        else:
            directory = ucfg.cfg['run']['directory']

            if len(directory) == 1:
                directory = directory[0]

            if self.all_subdirs is True:
                self.run_dirs = ([
                    directory + s for s in os.listdir(directory)
                    if (os.path.isdir(directory + s))
                ])
            else:
                self.run_dirs = ucfg.cfg['run']['directory']
                if type(self.run_dirs) != list:
                    self.run_dirs = [self.run_dirs]

        self.run_dirs.sort()

        ####################################################
        #         database
        ####################################################
        self.mysql = ucfg.cfg['database']['mysql']
        self.db_user = ucfg.cfg['database']['user']
        self.db_password = ucfg.cfg['database']['password']
        self.db_host = ucfg.cfg['database']['host']
        self.db_port = ucfg.cfg['database']['port']
        self.db_convert = ucfg.cfg['database']['convert_ws']
        self.add_basins = ucfg.cfg['database']['add_basins']
        self.db_overwrite = ucfg.cfg['database']['overwrite']
        self.properties = ucfg.cfg['database']['properties']
        self.sqlite = ucfg.cfg['database']['sqlite']

        base_bands = [
            'swi_z', 'evap_z', 'swe_z', 'depth', 'density', 'coldcont',
            'precip_z'
        ]

        for band in base_bands:
            if band not in self.properties:
                self.tmp_log.append(' WARNING! Config option [database] '
                                    'properties does not contain '
                                    '{}'.format(band))

        if ((self.mysql is not None)
                and ((self.db_user is None) or (self.db_password is None) or
                     (self.db_host is None) or (self.db_port is None))):
            raise Exception('If using config option [database] mysql, must '
                            'also supply user, password, host, and port')

        if self.sqlite is not None:
            if not os.path.isdir(os.path.dirname(self.sqlite)):
                raise Exception('{} does not contain a valid base '
                                'path'.format(self.sqlite))
            self.sqlite = 'sqlite:///' + self.sqlite
            self.db_type = 'sqlite'

            if self.mysql is not None:
                raise Exception('Config option [database] section contains '
                                'both "mysql" and "sqlite" entries, pick one.')
        else:
            self.db_type = 'sql'

        ####################################################
        #           validate                               #
        ####################################################
        self.val_stns = ucfg.cfg['validate']['stations']
        self.val_lbls = ucfg.cfg['validate']['labels']
        self.val_client = ucfg.cfg['validate']['client']
        self.wxdb_user = ucfg.cfg['validate']['user']
        self.wxdb_password = ucfg.cfg['validate']['password']
        self.wxdb_host = ucfg.cfg['validate']['host']
        self.wxdb_port = ucfg.cfg['validate']['port']
        self.point_values = ucfg.cfg['validate']['point_values']
        self.point_values_csv = ucfg.cfg['validate']['point_values_csv']
        self.point_values_date = ucfg.cfg['validate']['point_values_date']
        self.point_values_properties = ucfg.cfg['validate'][
            'point_values_properties']
        self.point_values_heading = ucfg.cfg['validate'][
            'point_values_heading']
        self.point_values_settings = ucfg.cfg['validate'][
            'point_values_settings']

        for n in range(0, 10):
            self.point_values_settings[n] = int(self.point_values_settings[n])

        if self.point_values and self.point_values_csv is None:
            self.point_values = False
            self.tmp_log.append(' Config option [validate] point_values_csv '
                                'was not supplied, point_values being set '
                                'to False')

        if self.point_values and self.point_values_date is None:
            self.point_values = False
            self.tmp_log.append(' Config option [validate] point_values_date '
                                'was not supplied, point_values being set '
                                'to False')

        ####################################################
        #           diagnostics                            #
        ####################################################
        self.diagnostics_flag = ucfg.cfg['diagnostics']['diagnostics']
        self.diag_basins = ucfg.cfg['diagnostics']['basins']
        self.diag_limit = ucfg.cfg['diagnostics']['limit']

        if self.diagnostics_flag:
            if self.diag_basins is not None:
                for basin in self.diag_basins:
                    if basin not in self.plotorder:
                        self.tmp_log.append(' Config [diagnostics] basin: "{}"'
                                            ' does not match [snowav] masks: '
                                            '"{}", diagnostics set to '
                                            'False'.format(
                                                basin, self.plotorder))
                        self.diagnostics_flag = False

        if 'snow_line' not in self.properties and self.diagnostics_flag:
            self.diagnostics_flag = False
            self.tmp_log.append(' Required properties in [database] properties'
                                ' for [diagnostics] does not exist, setting '
                                'diagnostics: False')

        self.inputs_flag = ucfg.cfg['diagnostics']['inputs_table']
        self.inputs_variables = ucfg.cfg['diagnostics']['inputs_variables']
        self.inputs_percentiles = ucfg.cfg['diagnostics']['inputs_percentiles']
        self.inputs_methods = ucfg.cfg['diagnostics']['inputs_methods']
        self.inputs_basins = ucfg.cfg['diagnostics']['inputs_basins']

        if self.inputs_basins is not None and self.plotorder is not None:
            for basin in self.inputs_basins:
                if basin not in self.plotorder:
                    self.tmp_log.append(
                        ' Config option [diagnostics] '
                        'inputs_basins: {} does not match what '
                        'was supplied in [snowav] masks: {}, '
                        'inputs set to '
                        'False'.format(basin, self.plotorder))
                    self.inputs_flag = False

        if self.inputs_flag:
            s = [x + ', ' for x in self.inputs_variables]
            self.tmp_log.append(' Using variables {} for inputs '
                                'summary'.format(''.join(s)))

            s = [x + ', ' for x in self.inputs_methods]
            self.tmp_log.append(' Using methods {} for inputs '
                                'summary'.format(''.join(s)))

        ####################################################
        #          plots                                   #
        ####################################################
        self.dpi = ucfg.cfg['plots']['dpi']
        self.depth_clip = ucfg.cfg['plots']['depth_clip']
        self.clims_percent = ucfg.cfg['plots']['clims_percent']
        self.subs_fig = ucfg.cfg['plots']['subs_fig']
        self.density_flag = ucfg.cfg['plots']['density']
        self.swi_flag = ucfg.cfg['plots']['swi']
        self.current_image_flag = ucfg.cfg['plots']['current_image']
        self.image_change_flag = ucfg.cfg['plots']['image_change']
        self.flt_image_change_clims = ucfg.cfg['plots'][
            'flt_image_change_clims']
        self.cold_content_flag = ucfg.cfg['plots']['cold_content']
        self.swe_volume_flag = ucfg.cfg['plots']['swe_volume']
        self.basin_total_flag = ucfg.cfg['plots']['basin_total']
        self.stn_validate_flag = ucfg.cfg['plots']['stn_validate']
        self.nash_sut_flag = ucfg.cfg['plots']['disp_nash_sut']
        self.stns_file = ucfg.cfg['plots']['stns_file']
        self.inputs_fig_flag = ucfg.cfg['plots']['inputs']
        self.plots_inputs_variables = ucfg.cfg['plots']['inputs_variables']
        self.compare_runs_flag = ucfg.cfg['plots']['compare_runs']
        self.compare_run_names = ucfg.cfg['plots']['compare_run_names']
        self.compare_run_labels = ucfg.cfg['plots']['compare_run_labels']
        self.compare_run_wys = ucfg.cfg['plots']['compare_run_wys']
        self.precip_depth_flag = ucfg.cfg['plots']['precip_depth']
        self.basin_detail_flag = ucfg.cfg['plots']['basin_detail']
        self.update_file = ucfg.cfg['plots']['update_file']
        self.figsize = ucfg.cfg['plots']['fig_size']
        self.write_properties = ucfg.cfg['plots']['write_properties']
        self.point_values_flag = ucfg.cfg['plots']['point_values']

        if self.flt_image_change_clims[0] < 0:
            self.flt_image_change_clims[0] = 0
        if self.flt_image_change_clims[1] > 100:
            self.flt_image_change_clims[1] = 100

        if (self.write_properties is not None
                and type(self.write_properties) != list):
            self.write_properties = [self.write_properties]

        numbers = ucfg.cfg['plots']['update_numbers']

        if numbers is not None:
            if type(numbers) != list:
                numbers = [numbers]
            self.update_numbers = [x - 1 for x in numbers]
        else:
            self.update_numbers = None

        if (self.compare_runs_flag and ((self.compare_run_names is None) or
                                        (self.compare_run_labels is None)
                                        or self.compare_run_wys is None)):
            self.tmp_log.append(' Config option [plots] compare_runs set to '
                                'True, but one of compare_run_names, '
                                'compare_run_labels, or compare_run_wys is '
                                'empty, setting compare_runs to False')
            self.compare_runs_flag = False

        if (self.compare_runs_flag and
            (len(self.compare_run_names) != len(self.compare_run_labels))):
            self.tmp_log.append(' Config option [plots] compare_runs set to '
                                'True, must supply equal length '
                                'compare_run_names and compare_run_labels, '
                                'resetting compare_runs to False')
            self.compare_runs_flag = False

        if self.update_file is not None:
            self.flt_flag = True
        else:
            self.flt_flag = False

        if (self.stn_validate_flag and (self.val_client is None)
                or (self.val_stns is None) or (self.val_lbls is None)
                or (self.wxdb_user is None) or (self.wxdb_password is None)):
            self.tmp_log.append(' Config option [plots] stn_validate is being '
                                'set to False')

            self.stn_validate_flag = False

        if len(self.point_values_settings) != 14:
            self.tmp_log.append(' Expected [validate] point_values_settings '
                                'to have 14 values, point_values set to False')
            self.point_values_flag = False

        for var in self.plots_inputs_variables:
            if var not in self.inputs_variables:
                self.plots_inputs_variables.remove(var)
                self.tmp_log.append(' Config option [plots] inputs_variables '
                                    'value {} not present in [diagnostics] '
                                    'inputs_variables, being '
                                    'removed'.format(var))

        ####################################################
        #          report                                  #
        ####################################################
        self.report_flag = ucfg.cfg['report']['report']
        self.print_latex = ucfg.cfg['report']['print_latex']
        self.report_name = ucfg.cfg['report']['file']
        self.rep_title = ucfg.cfg['report']['title']
        self.rep_path = ucfg.cfg['report']['save_path']
        self.env_path = ucfg.cfg['report']['env_path']
        self.templ_path = ucfg.cfg['report']['templ_path']
        self.tex_file = ucfg.cfg['report']['tex_file']
        self.summary_file = ucfg.cfg['report']['summary']
        self.figs_tpl_path = ucfg.cfg['report']['figs_tpl_path']
        self.flight_figs = ucfg.cfg['report']['flight_figs']
        self.tables = ucfg.cfg['report']['tables']
        self.report_diagnostics = ucfg.cfg['report']['diagnostics']
        self.report_diagnostics_day = ucfg.cfg['report']['diagnostics_day']
        self.rep_dplcs = ucfg.cfg['report']['decimals']

        if (self.report_diagnostics
                and (not self.inputs_fig_flag or not self.diagnostics_flag)):
            self.tmp_log.append(" [report] diagnostics: True, but must also "
                                "have [plots] inputs: True and [diagnostics] "
                                "diagnostics: True, setting to False")
            self.report_diagnostics = False

        if self.report_diagnostics and self.report_diagnostics_day[0] != 'any':

            if (calendar.day_name[datetime.now().weekday()]
                    not in self.report_diagnostics_day):
                self.report_diagnostics = False
                self.tmp_log.append(" Per [report] diagnostics_day: {}, "
                                    "setting diagnostics: "
                                    "False".format(
                                        self.report_diagnostics_day))

        self.rep_swi_flag = ucfg.cfg['report']['swi']
        if not self.swi_flag:
            self.rep_swi_flag = False

        self.rep_image_change_flag = ucfg.cfg['report']['image_change']
        if not self.image_change_flag:
            self.rep_image_change_flag = False

        self.rep_cold_content_flag = ucfg.cfg['report']['cold_content']
        if not self.cold_content_flag:
            self.rep_cold_content_flag = False

        self.rep_swe_volume_flag = ucfg.cfg['report']['swe_volume']
        if not self.swe_volume_flag:
            self.rep_swe_volume_flag = False

        self.rep_basin_total_flag = ucfg.cfg['report']['basin_total']
        if not self.basin_total_flag:
            self.rep_basin_total_flag = False

        self.rep_stn_validate_flag = ucfg.cfg['report']['stn_validate']
        if not self.stn_validate_flag:
            self.rep_stn_validate_flag = False

        self.rep_compare_runs_flag = ucfg.cfg['report']['compare_runs']
        if not self.compare_runs_flag:
            self.rep_compare_runs_flag = False

        self.rep_precip_depth_flag = ucfg.cfg['report']['precip_depth']
        if not self.precip_depth_flag:
            self.rep_precip_depth_flag = False

        # check paths to see if they need default snowav path
        if self.env_path is None:
            self.env_path = os.path.abspath(
                os.path.join(snowav.__path__[0],
                             "report/template/section_text"))
        if self.templ_path is None:
            self.templ_path = os.path.abspath(
                os.path.join(snowav.__path__[0], "report/template"))
        if self.summary_file is None:
            self.summary_file = os.path.abspath(
                os.path.join(
                    snowav.__path__[0],
                    "report/template/section_text/report_summary.txt"))
        if self.tex_file is None:
            self.tex_file = os.path.abspath(
                os.path.join(snowav.__path__[0],
                             "report/template/snowav_report.text"))
        if self.figs_tpl_path is None:
            self.figs_tpl_path = os.path.abspath(
                os.path.join(snowav.__path__[0], "report/figs"))

        ####################################################
        #           query                                  #
        ####################################################
        self.query_flag = ucfg.cfg['query']['query']
        self.q_basins = ucfg.cfg['query']['basins']
        self.q_value = ucfg.cfg['query']['value']
        self.q_run_name = ucfg.cfg['query']['run_name']
        self.q_print_all_runs = ucfg.cfg['query']['print_all_runs']
        self.q_start_date = ucfg.cfg['query']['start_date']
        self.q_end_date = ucfg.cfg['query']['end_date']
        self.q_total = ucfg.cfg['query']['total']
        self.q_output = ucfg.cfg['query']['output']
        self.q_csv_base_path = ucfg.cfg['query']['csv_base_path']
        self.q_database = ucfg.cfg['query']['database']

        ####################################################
        #           inflow                                 #
        ####################################################
        self.inflow_flag = ucfg.cfg['inflow']['inflow']
        self.inflow_data = ucfg.cfg['inflow']['inflow_data']
        self.summary_csv = ucfg.cfg['inflow']['summary_csv']
        self.inflow_headings = ucfg.cfg['inflow']['inflow_headings']
        self.basin_headings = ucfg.cfg['inflow']['basin_headings']
        self.sheet_name = ucfg.cfg['inflow']['sheet_name']
        self.skiprows = ucfg.cfg['inflow']['skiprows']
        self.overwrite = ucfg.cfg['inflow']['overwrite']
        self.file_base = ucfg.cfg['inflow']['file_base']
        self.date_idx = ucfg.cfg['inflow']['date_idx']
        self.convert = ucfg.cfg['inflow']['convert']

        self.ucfg = ucfg