def main():

    parameter_sweep_path = pjoin(mm.rootdir(), 'control_scripts/parameter-sweep.py')

    print(parameter_sweep_path)
    # Check parameter sweep exists
    assert(os.path.isfile(parameter_sweep_path))

    # Check we get output when runs correctly
    subp.check_call([parameter_sweep_path, '-p', 'self_test', '--clean',
                     '--no-build'])
    root = pjoin(mm.rootdir(), 'experiments/parameter_sweeps/self_test')
    for _, odirs, _ in os.walk(root):
        for odir in odirs:
            odir = pjoin(root, odir)
            print("checking files in", odir)
            assert os.path.isfile(pjoin(odir, "trace")), pjoin(odir, "trace")
            assert(os.path.isfile(pjoin(odir, "info")))
            assert(os.path.isfile(pjoin(odir, "run_script")))
            assert(not os.path.isfile(pjoin(odir, "FAILED")))

    assert(os.path.isfile(pjoin(root, "parameter_file")))


    # and when it fails
    print("Note that the following run is supposed to fail!")
    subp.check_call([parameter_sweep_path, '-p', 'fail_test', '--clean',
                     '--no-build'])
    root = pjoin(mm.rootdir(), 'experiments/parameter_sweeps/fail_test')
    for _, odirs, _ in os.walk(root):
        for odir in odirs:
            odir = pjoin(root, odir)
            assert(os.path.isfile(pjoin(odir, "trace")))
            assert(os.path.isfile(pjoin(odir, "info")))
            assert(os.path.isfile(pjoin(odir, "run_script")))
            assert(os.path.isfile(pjoin(odir, "FAILED")))

    assert(os.path.isfile(pjoin(root, "parameter_file")))


    return 0
def main():

    results_root = pjoin(mm.rootdir(), "experiments", "parameter_sweeps", "odblock-eigs")

    for _rdir in os.listdir(results_root):
        results_dir = pjoin(results_root, _rdir)

        data = mm.parse_run(results_dir)

        if data is None:
            continue

        print("\nrefinement level", data['refinement'])
        print("disable-ms?", data['disable-ms'])

        first_m_block = 2
        nblock = 5

        # Just first Jacobian for now
        with warnings.catch_warnings():
            A = omat.import_blocks(pjoin(results_dir, "J_3_1_block"), nblock)

        # Get only LLG blocks
        A = omat.sub_matrix(A, first_m_block)

        # Get only offdiagonal blocks
        A = omat.off_diagonal_blocks(A)

        evs = []
        non_sym = []
        for block in A.flat:
            if block.nnz > 0:
                ev, evec = sp.sparse.linalg.eigs(block)
                evs.append(ev)
                TT = block - block.T

                nnz = len(filter(lambda x: x> 1e-8, TT.data))
                non_sym.append(nnz)

                # if nnz > 0:
                #     print(sp.mean(block.data))
                #     print(TT)


        # print("overall abs", map(maxabs, evs))
        # print("max real part", map(maxreal, evs))
        print("max imaginary part", max(map(maximag, evs)))

        print("max nnz in B - B^T", max(non_sym))



    return 0
def main():
    """Run driver multiple times in parallel with arguments specified by a file
    in etc/parameter_sets.

    Parameter file format is either:

    1) a dict of cli args and lists of their values, e.g.:
    {
    '-dt' : 0.1,
    '-ref' : [1, 2, 3],
    }
    will run with `-dt 0.1 -ref 1` , `-dt 0.1 -ref 2` and `-dt 0.1 -ref 3`.


    2) A tuple consisting of a dict as above and (any number of) lists
    of dicts. e.g.

    ({...}, [{'-a' : 1, '-b' : 2}, {'-a' : 4, '-b' : [4, 5, 6]}], ... )

    each list of dicts contains arguments which only make sense when
    used together. Each of these dicts should be in the same format as
    the main dict. Each one is merged into the main dict (using .update)
    and then used similarly to the main dict in 1).

    Note that all of the additional dicts must contain the same args.
    """

    # Parse inputs
    # ============================================================

    parser = argparse.ArgumentParser(description=main.__doc__,

    # Don't mess up my formating in the help message
    formatter_class=argparse.RawDescriptionHelpFormatter)

    parser.add_argument('--debug-mode', action='store_true',
                        help = 'Enable debugging mode (run in serial).')

    parser.add_argument('--parameters', '-p', action='append',
                        help = 'Do a standard parameter sweep with the specified parameter set.')

    parser.add_argument('--clean', action='store_true',
                        help='clean up old results from the target folder')

    parser.add_argument('--ncores', '-j', '-n', default=mp.cpu_count(),
                        type=int, help='Number of processes to run at once.')

    parser.add_argument('--no-build', action='store_true',
                        help="Don't rebuild anything")

    parser.add_argument('--dry-run', action='store_true',
                        help="Don't actually do anything, just list the parameters to run.")

    args = parser.parse_args()


    for parameter_set in args.parameters:

        # Find the parameter set
        # ============================================================

        search_root = pjoin(mm.rootdir(), "etc", "parameter_sets")

        # Recurively find files named parameter_set in search_root
        parameter_files = []
        for root, dirs, files in os.walk(search_root, followlinks=True):
            for f in files:
                if f == parameter_set:
                    parameter_files.append(pjoin(root, f))

        # Error check number of files
        if len(parameter_files) > 1:
            sys.stderr.write("Found multiple files named "+ parameter_set + ": "
                             + " ".join(parameter_files) + "\n")
            return 5
        elif len(parameter_files) == 0:
            sys.stderr.write("Couldn't find a file named "+ parameter_set
                              + " in " + search_root + "\n")
            return 6
        else:
            parameter_file = parameter_files[0]



        # Parse parameters file
        # ============================================================

        output_root = pjoin(mm.rootdir(), "experiments", "parameter_sweeps",
                            '_'.join(parameter_set.split()))

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

        print(args_file)

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


        if args.dry_run:
            if extra is not None:
                parameter_dicts = sum([mm.generate_argdicts(args_dict, a) for a in extra], [])
            else:
                parameter_dicts = mm.generate_argdicts(args_dict)

            pprint(parameter_dicts)

            return 0


        # Make sure we're ready to go
        # ============================================================

        # Maybe build things
        if not args.no_build:

            # Make sure micromag library is up to date
            driver_folder = os.path.dirname(mm.driver_path())
            library_folder = pjoin(driver_folder, "../../")

            print("Building and installing libraries from", library_folder)
            subp.check_call(['make', '--silent', '--keep-going',
                             'LIBTOOLFLAGS=--silent'], cwd=library_folder)
            subp.check_call(['make', 'install', '--silent', '--keep-going',
                             'LIBTOOLFLAGS=--silent'], cwd=library_folder)

            print("Building driver in", driver_folder)
            subp.check_call(['make', '--silent', '--keep-going',
                             'LIBTOOLFLAGS=--silent'], cwd=driver_folder)

            # Make sure the binaries are up to date (if they aren't just the
            # default one).
            binaries = args_dict.get('-binary')
            if binaries is not None:
                driver_folders = [os.path.abspath(os.path.dirname(d)) for d in binaries]
                for f in driver_folders:
                    build_driver(f)


        # Remove old stuff if requested
        if args.clean and os.path.isdir(output_root):
            print("Cleaning out", output_root)
            # recursive_check_filenames_rm_safe(output_root)
            shutil.rmtree(output_root)
            os.mkdir(output_root)

        # Copy parameters file to output dir
        os.makedirs(output_root, exist_ok=True)
        shutil.copyfile(parameter_file, pjoin(output_root, "parameter_file"))



        # Run it
        # ============================================================

        print("Running parameter sweep with parameter set", parameter_set)
        print("Output is going into", output_root)
        mm.run_sweep(args_dict, output_root,
                     extra_argsets=extra,
                     serial_mode=args.debug_mode,
                     processes=args.ncores)

    return 0