Skip to content

Commit

Permalink
A working CLI implementation (thouska#139, thouska#143)
Browse files Browse the repository at this point in the history
  • Loading branch information
philippkraft committed Aug 28, 2018
1 parent 102d635 commit 7b158e4
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 0 deletions.
94 changes: 94 additions & 0 deletions spotpy/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
from __future__ import division, print_function, unicode_literals

import click
import inspect
from . import algorithms, database, describe
import click
import inspect
import io
import os


def get_config_from_file():
"""
Gets the spotpy configuration from a config file 'spotpy.conf'.
Example:
sampler = mc
dbtype = csv
parallel = seq
# This is a comment
runs = 10
"""
config = {}
if os.path.exists('spotpy.conf'):
with io.open('spotpy.conf') as f:
for line in f:
if not line.strip().startswith('#'):
try:
k, v = line.split('=', 1)
config[k.strip()] = v.strip()
except ValueError:
pass
return config


def get_sampler_from_string(sampler_name):
return getattr(algorithms, sampler_name)


def make_type_from_module(module, *exclude):

def use(cl):
# Check if class name starts with an exclusion term
return inspect.isclass(cl) and not any([cl.__name__.startswith(ex) for ex in ('_', ) + exclude])
members = inspect.getmembers(module, use)
return click.Choice([n for n, m in members if not n.startswith('_')])



@click.group(context_settings=dict(help_option_names=['-h', '--help']))
def cli():
pass


@cli.command()
@click.pass_context
@click.option('--sampler', '-s', type=make_type_from_module(algorithms), default='mc',
help='Select the spotpy sampler')
@click.option('--dbformat', type=make_type_from_module(database, 'Pick'), default='ram',
help='The type of the database')
@click.option('--dbname', type=click.STRING, help='The name of the database, leave open for ram')
@click.option('--parallel', '-p', type=click.Choice(['seq', 'mpc', 'mpi']), default='seq',
help='Parallelization: seq = no parallelization, mpi = MPI (for clusters), mpc = multiprocessing')
@click.option('--runs', '-n', type=click.INT, default=1, help='Number of runs')
def run(ctx, **kwargs):
"""
Runs a sampler for automatic calibration
"""
setup = ctx.obj
sampler_class = get_sampler_from_string(kwargs.pop('sampler'))
runs = kwargs.pop('runs')
sampler = sampler_class(setup, **kwargs)
sampler.sample(runs)


@cli.command()
@click.pass_context
def gui(ctx):
"""
Shows a GUI for manual calibration
"""
from spotpy.gui.mpl import GUI
setup = ctx.obj
gui = GUI(setup)
gui.show()


def main(setup):
# Prevent help text from wrapping
cli.help = '\b\n' + describe.setup(setup).replace('\n\n', '\n\b\n')
config = get_config_from_file()
cli(obj=setup, auto_envvar_prefix='SPOTPY', default_map=config)

16 changes: 16 additions & 0 deletions spotpy/examples/cli_cmf_lumped.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
Shows the usage of the matplotlib GUI
Needs at least Python 3.5
"""

from __future__ import division, print_function, unicode_literals


from spotpy.cli import main
#from spotpy.examples.spot_setup_cmf_lumped import SingleStorage as spot_setup
from spotpy.examples.spot_setup_rosenbrock import spot_setup

if __name__ == '__main__':
setup = spot_setup()
main(setup)
4 changes: 4 additions & 0 deletions spotpy/examples/spotpy.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
sampler = abc
dbtype = csv
parallel = seq
# This is a comment

0 comments on commit 7b158e4

Please sign in to comment.