def run_sweep(args_dict, base_outdir, extra_argsets=None, **kwargs):
    """Run a parameter sweep


    args_dict is a dictionary of argument lists.

    extra_argsets is a list of argdicts for arguments which have to come
    in groups.
    """

    # Generate list of parameter sets
    if extra_argsets is not None:
        parameter_dicts = sum([generate_argdicts(args_dict, a) for a in extra_argsets], [])
    else:
        parameter_dicts = generate_argdicts(args_dict, None)

    # Find out which arguments have different values in different runs
    varying_args = utils.find_varying_value_keys(parameter_dicts)

    # Run on all args.
    out = utils.parallel_map(_run, parameter_dicts, it.repeat(base_outdir),
                             it.repeat(varying_args), **kwargs)

    # Extract err_codes etc into separate lists and force execution (just
    # in case it's still an iterator)
    err_codes, outdirs = utils.unzip(list(out))

    return err_codes, outdirs
def convergence_rate(dataset, error_norm_norm=max):
    """For a set of convergence tests calculate the rate of covergence.
    Parameter "error_norm_norm" is used to convert the list of error
    norms at each time step to a single error norm.
    """

    # Check that we have a set of convergence tests
    assert all([d['-convergence-test'] == "1" for d in dataset])

    # Check that all parameters other than -ref match
    def arguments_match(data1, data2, exclusions=['-ref', '-outdir']):
        for k, v in data1.items():
            if is_arg_key(k) and not k in exclusions:
                if v != data2[k]:
                    return False

        return True
    assert all([arguments_match(dataset[1], d) for d in dataset[1:]])


    # Extract data to be fitted
    dts, errs = utils.unzip([( sp.mean(d['dts']), error_norm_norm(d['error_norms']) )
                             for d in dataset])

    # fit the data to a 2nd order polynomial
    def f(x, a, b, c):
        return a*(x**b) + c
    parameters, covar = sp.optimize.curve_fit(f, dts, errs)
    rate = parameters[1]     # rate of convergence = power of x (second
                             # parameter).

    return rate
def main():

    parser = argparse.ArgumentParser()
    parser.add_argument('parameter_file')
    args = parser.parse_args()

    with open(args.parameter_file, 'r') as pfile:
        args_file = ast.literal_eval(pfile.read())

    try:
        args_dict = args_file[0]
        extra = list(args_file[1:])
    except KeyError:
        args_dict = args_file
        extra = None

    argdicts = sum([mm.generate_argdicts(args_dict, extra_args_dicts=e) for e in extra], [])

    arglists, _, _ = utils.unzip([mm.argdict2list(a) for a in argdicts])

    for a in arglists:
        print("./driver", ' '.join(a), "\n")

    return 0