Commit ec248bb2 authored by Clément Haëck's avatar Clément Haëck
Browse files

Up default arguments parsing

Place option type in conf file as a string.
Add support for default fixes.
Add comments in example conf file.
parent 9f1556a2
......@@ -2,12 +2,13 @@
import argparse
import configparser
from datetime import datetime
import itertools
import os
from os import path
import re
import sys
from datetime import datetime
from os import path
from typing import List
# Scripts repository
try:
......@@ -34,20 +35,30 @@ if not path.isfile(_config_file):
_config.read(_config_file)
DEFAULTS = {k: _config.get('defaults', k)
for k in _config.options('defaults')}
_supported_types = {t.__name__: t for t in [int, str, bool, float, type(None)]}
DEFAULTS = {}
DEFAULTS_TYPES = {}
for k in _config.options('defaults'):
tp_str, val = _config.get('defaults', k).split(',')
tp = _supported_types[tp_str]
val = val.strip()
if tp_str == 'bool':
val = _config._convert_to_boolean(val)
DEFAULTS[k] = tp(val) if val else tp()
DEFAULTS_TYPES[k] = tp
# Fixes are empty by default
DEFAULTS['fixes'] = {}
# Climato is None
DEFAULTS['climato'] = None
def _fixes_as_dict(fixes: List[str]):
return {k: v for k, v in fixes}
# Get the correct type
for k in ['year', 'days', 'number', 'coef']:
DEFAULTS[k] = int(DEFAULTS[k])
for k in ['scale']:
DEFAULTS[k] = float(DEFAULTS[k])
if 'fixes' in DEFAULTS:
d = DEFAULTS['fixes'].split()
if len(d) % 2 != 0:
raise ValueError("Default fixes are not grouped in pairs.")
d = [[d[i], d[i+1]] for i in range(0, len(d), 2)]
DEFAULTS['fixes'] = _fixes_as_dict(d)
DEFAULTS_TYPES['fixes'] = dict
def check_output_dir(odir, log=None, file=False):
......@@ -85,50 +96,33 @@ def get_args(args, add_args=None, description=''):
args: list of str
List of typical arguments that will automatically added to the parser,
with the default value taken from the configuration file.
data_type, region, year, days, scale, number, coef, zone, fix,
date (default is '200701')
'date' will be transformed into argument 'date': a datetime instance,
and 'date_str', a tuple of strings (year, month, day).
Specifying day is optional.
See the configuration file to see details on available arguments.
There can be any number of 'fix' arguments. Each is a couple of
key (int/str) and value (str). Each is appended to dictionnary of fixes
in args['fixes'].
See filefinder.Finder.fix_matchers().
'fixes' is a special case. It adds a '-fix' argument to the command
line. There can be any number of 'fix' arguments. Each is a couple of
key (str) and value (str). Each is appended to dictionnary of fixes
in args['fixes']. See filefinder.Finder.fix_matchers().
add_args: callable
Function that take an argparse.ArgumentParser and add arguments to it.
Arguments can be overwritten.
"""
parser = argparse.ArgumentParser(
formatter_class=argparse.RawTextHelpFormatter,
description=description,
conflict_handler='resolve')
def add_arg(name, type, default=None):
if default is None:
default = DEFAULTS[name]
if name in args:
parser.add_argument('-{}'.format(name), type=type,
default=default)
add_arg('data_type', str, 'OC')
add_arg('region', str)
add_arg('year', int)
add_arg('date', str, '{:04d}{:02d}'.format(DEFAULTS['year'], 1))
add_arg('days', int)
add_arg('scale', float)
add_arg('number', int)
add_arg('coef', int)
add_arg('zone', str)
add_arg('level', str)
add_arg('grid_file', str)
add_arg('season', str)
for name in args:
if name not in DEFAULTS:
raise KeyError(f"'{name}' not in defaults parameters.")
parser.add_argument('-{}'.format(name),
type=DEFAULTS_TYPES[k],
default=DEFAULTS[k])
if 'fixes' in args:
parser.add_argument('-fix', nargs=2, type=str, action='append',
default=list(
itertools.chain(*DEFAULTS['fixes'].items())))
parser.add_argument(
'-fix', nargs=2, type=str, action='append',
default=list(itertools.chain(DEFAULTS['fixes'].items())))
if add_args is not None:
add_args(parser)
......@@ -136,9 +130,7 @@ def get_args(args, add_args=None, description=''):
dargs = vars(parser.parse_args())
if 'fixes' in args:
fix = [i for j in dargs['fix'] for i in j]
fix = dict(zip([i for i in fix[::2]], fix[1::2]))
dargs['fixes'] = fix
dargs['fixes'] = _fixes_as_dict(dargs['fix'])
if 'date' in dargs:
date = re.match(r'(\d\d\d\d)[-\s/]?(\d\d)[-\s/]?(\d\d)?',
......
# This is an example of the lib/conf.ini file
# Defaults parameters used by lib.get_args.
# Each key represent a parameter name.
# Each value represent the type of the parameter then its value,
# separated by a comma.
# If the value is left empty, the default type value will be used
# (0 for an integer for instance).
[defaults]
region: GS
year: 2007
days: 1
scale: 20
number: 1
coef: 0
level: L3
zone: gyre
grid_file: boxgrid_5.0_5.0
season: spring
region: str, GS
# Region name. It corresponds to the data folder to use:
# ${SUBMESO_COLOR_DATA_DIR}/<region>/...
days: int, 1
# Temporal resolution in days.
year: int, 2007
# Default year for yearly scripts.
date: str, 200701
# Year and month for monthly scripts.
# It will be transformed into argument 'date': a datetime instance,
# and 'date_str', a tuple of strings (year, month, day).
# Specifying day is optional.
climato: NoneType,
# The climatology data to load. If None, don't use climatology.
# Otherwise an integer that defines the climatology temporal resolution,
# 12 for monthly for instance.
fixes: str,
# Default fixes. Won't be replaced by other command line fixes,
# they will only be added to the defaults.
# Fixes should be indicated as space separated key value pairs.
# Ex: fixes: str, m 01 d 01
# This will be converted to a dictionnary.
# I do not use it, it is not fully tested.
level: str, L3
# Copernicus chlorophyll level to use. L3 or L4.
zone: str, gyre
# Zone to make computations on. Can be various.
data_type: str, OC
# Differentiates between OC and SST for MODIS data.
# HI related arguments:
scale: float, 30.
# Size of the HI rolling window.
# Float, but is generally a decade. See lib.data.hi.
number: int, 2
# Indicates a way of computing the HI.
# Can be used to have different 'versions'.
# I use it as such: 1 is for HI computed from MODIS SST,
# and 2 from the ESA-CCI/C3S SST.
coef: int, 0
# Same as number, but for the normalization coefficients to use.
# 0 is standard. Above are variations (like twice as much bimodality
# for instance).
threshold: float, 15.0
# HI threshold to discriminate fronts.
thr_lo: float, 6.0
thr_hi: float, 15.0
# HI thresholds to discriminates fronts.
# Under lo: no front
# Above hi: intense mesoscale front
# Between the two (mid): submesoscale front
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment