import os

import numpy as np
import skopt
import torch
import torchvision
from matplotlib import pyplot as plt
import tabulate

import scripts.plot as plot
from curvature.lenet5 import lenet5
from curvature.resnet import resnet18
from curvature.utils import setup, get_eigenvalues, accuracy, get_eigenvectors, expected_calibration_error

import matplotlib
matplotlib.use("agg")

def load_data(args, model, data='imagenet', estimator="kfac", ood=False):
    if estimator in ["swag", "swa"] and data == 'imagenet':
        data_path = os.path.join(args.results_dir, model, "data", "swag", f"ood_{estimator}" if ood else estimator)
        data = np.load(data_path + ".npz")
        return data['targets'], None, data['predictions']

    filename = f"{args.prefix}{model}_{data}{args.suffix}"
    data_path = os.path.join(args.results_dir, model, "data", estimator, filename)
    data = np.load(data_path + ".npz")
    if ood:
        return data['labels'], data['ood_predictions'], data['bnn_ood_predictions']
    return data['labels'], data['predictions'], data['bnn_predictions']

def ecdf(args):
    fig, ax = plt.subplots(figsize=(12, 7), tight_layout=True)

    labels, predictions, bnn_predictions = load_data(args, args.model, args.data, args.estimator)
    labels, ood_predictions, bnn_ood_predictions = load_data(args, args.model, args.data, args.estimator, ood=True)

    plot.inv_ecdf_vs_pred_entropy(predictions, color='dodgerblue', linestyle='--', axis=ax)
    plot.inv_ecdf_vs_pred_entropy(ood_predictions, color='crimson', linestyle='--', axis=ax)
    plot.inv_ecdf_vs_pred_entropy(bnn_predictions, color='dodgerblue', axis=ax)
    plot.inv_ecdf_vs_pred_entropy(bnn_ood_predictions, color='crimson', axis=ax)
    ax.legend([f"NN {args.data.upper()} | Acc.: {accuracy(predictions, labels):.2f}%",
               f"NN OOD",
               f"BNN {args.data.upper()} | Acc.: {accuracy(bnn_predictions, labels):.2f}%",
               f"BNN OOD"], fontsize=16, frameon=False)
    filename = f"{args.prefix}{args.model}_{args.data}{args.suffix}"
    plt.savefig(args.results_dir + f"/figures/ecdf_{filename}.pdf", format='pdf', dpi=1200)

def entropy_histogram(args):
    if args.estimator in ['swa', 'swag']:
        labels, _, predictions = load_data(args, args.model, args.data, args.estimator)
        _, _, ood_predictions = load_data(args, args.model, args.data, args.estimator, ood=True)
    elif args.estimator == 'sgd':
        labels, predictions, _ = load_data(args, args.model, args.data, 'kfac')
        _, ood_predictions, _ = load_data(args, args.model, args.data, 'kfac', ood=True)
    else:
        labels, _, predictions = load_data(args, args.model, args.data, args.estimator)
        _, _, ood_predictions = load_data(args, args.model, args.data, args.estimator, ood=True)
    acc = accuracy(predictions, labels)
    ece = expected_calibration_error(predictions, labels)[0]
    label = f"In Class | Acc.: {acc:.2f}% | ECE: {100 * ece:.2f}%"

    fig_path = os.path.join(args.results_dir, args.model, "figures", args.estimator)
    os.makedirs(fig_path, exist_ok=True)

    filename = f"{args.prefix}{args.model}_{args.data}{args.suffix}"
    plot.entropy_hist(predictions, ood_predictions, path=os.path.join(fig_path, f"{filename}_entropy.pdf"), label=label)

def calibration(args):
    fig, ax = plt.subplots(figsize=(12, 7), tight_layout=True)

    c1 = next(ax._get_lines.prop_cycler)['color']
    c2 = next(ax._get_lines.prop_cycler)['color']
    c3 = next(ax._get_lines.prop_cycler)['color']
    c4 = next(ax._get_lines.prop_cycler)['color']
    c5 = next(ax._get_lines.prop_cycler)['color']
    c6 = next(ax._get_lines.prop_cycler)['color']
    c7 = next(ax._get_lines.prop_cycler)['color']

    try:
        labels, predictions, kfac_predictions = load_data(args, args.model, args.data, "kfac")
        plot.calibration(predictions, labels, color=c1, label=f"SGD", axis=ax)
        plot.calibration(kfac_predictions, labels, color=c2, label="KFAC-Laplace", axis=ax)
    except FileNotFoundError:
        print(f"Data for model {args.model} and estimator SGD/KFAC not available.")
    try:
        diag_labels, _, diag_predictions = load_data(args, args.model, args.data, "diag")
        plot.calibration(diag_predictions, diag_labels, color=c3, label="Diag-Laplace", axis=ax)
    except FileNotFoundError:
        print(f"Data for model {args.model} and estimator DIAG not available.")
    try:
        efb_labels, _, efb_predictions = load_data(args, args.model, args.data, "efb")
        plot.calibration(efb_predictions, efb_labels, color=c4, label="EFB-Laplace", axis=ax)
    except FileNotFoundError:
        print(f"Data for model {args.model} and estimator EFB not available.")
    try:
        inf_labels, _, inf_predictions = load_data(args, args.model, args.data, "inf")
        plot.calibration(inf_predictions, inf_labels, color=c5, label="INF-Laplace", axis=ax)
    except FileNotFoundError:
        print(f"Data for model {args.model} and estimator INF not available.")
    try:
        swag_labels, _, swag_predictions = load_data(args, args.model, args.data, "swag")
        swa_labels, _, swa_predictions = load_data(args, args.model, args.data, "swa")
        plot.calibration(swa_predictions, swa_labels, color=c6, label="SWA", axis=ax)
        plot.calibration(swag_predictions, swag_labels, color=c7, label="SWAG", axis=ax)
    except FileNotFoundError:
        print(f"Data for model {args.model} and estimator SWAG/SWA not available.")

    filename = f"{args.prefix}{args.model}_{args.data}{args.suffix}"
    plt.savefig(args.results_dir + f"/figures/calibration_{filename}.pdf", format='pdf', dpi=1200)

def calibration_overview(args):
    fig, ax = plt.subplots(figsize=(12, 7), tight_layout=True)

    all_nets = ['resnet18', 'resnet34', 'resnet50', 'resnet101', 'resnet152',
                'densenet121', 'densenet161', 'densenet169', 'densenet201',
                'googlenet_x', 'inception_v3', 'wide_resnet50_2', 'vgg16', 'alexnet_x']

    nets = all_nets
    det_list = tuple(all_nets) if args.estimator != 'none' else all_nets
    bnn_list = all_nets if args.estimator != 'none' else []
    for name in nets:
        try:
            labels, predictions, bnn_predictions = load_data(args, name, args.data,
                                                             args.estimator if args.estimator != 'none' else 'kfac')
            color = next(ax._get_lines.prop_cycler)['color']

            if name in det_list and isinstance(det_list, list):
                plot.calibration(predictions, labels, color=color, label=name, axis=ax)
            elif name in bnn_list and isinstance(bnn_list, list):
                plot.calibration(bnn_predictions, labels, color=color, label=name, axis=ax)

            if name in det_list and isinstance(det_list, tuple):
                plot.calibration(predictions, labels, axis=ax, alpha=0.3, color=color, linestyle='--')
            elif name in bnn_list and isinstance(bnn_list, tuple):
                plot.calibration(bnn_predictions, labels, axis=ax, alpha=0.3, color=color, linestyle='--')
        except FileNotFoundError:
            print(f"Data for model {name} not available.")
    plt.savefig(
        args.results_dir + f"/figures/calibration_overview_{args.estimator if args.estimator != 'none' else ''}.pdf",
        format='pdf', dpi=1200)

def out_of_domain(args):
    fig, ax = plt.subplots(figsize=(12, 7), tight_layout=True)

    c1 = next(ax._get_lines.prop_cycler)['color']
    c2 = next(ax._get_lines.prop_cycler)['color']
    c3 = next(ax._get_lines.prop_cycler)['color']
    c4 = next(ax._get_lines.prop_cycler)['color']
    c5 = next(ax._get_lines.prop_cycler)['color']
    c6 = next(ax._get_lines.prop_cycler)['color']
    c7 = next(ax._get_lines.prop_cycler)['color']

    try:
        labels, predictions, kfac_predictions = load_data(args, args.model, args.data, "kfac")
        ood_labels, ood_predictions, ood_kfac_predictions = load_data(args, args.model, args.data, "kfac", ood=True)
        plot.inv_ecdf_vs_pred_entropy(ood_predictions, "SGD", c1, axis=ax)
        plot.inv_ecdf_vs_pred_entropy(ood_kfac_predictions, "KFAC-Laplace", c2, axis=ax)
        plot.inv_ecdf_vs_pred_entropy(predictions, color=c1, linestyle='--', axis=ax)
        plot.inv_ecdf_vs_pred_entropy(kfac_predictions, color=c2, linestyle='--', axis=ax)
    except FileNotFoundError:
        print(f"Data for model {args.model} and estimator SGD/KFAC not available.")
    try:
        diag_labels, _, diag_predictions = load_data(args, args.model, args.data, "diag")
        ood_diag_labels, _, ood_diag_predictions = load_data(args, args.model, args.data, "diag", ood=True)
        plot.inv_ecdf_vs_pred_entropy(ood_diag_predictions, "Diag-Laplace", c3, axis=ax)
        plot.inv_ecdf_vs_pred_entropy(diag_predictions, color=c3, linestyle='--', axis=ax)
    except FileNotFoundError:
        print(f"Data for model {args.model} and estimator DIAG not available.")
    try:
        efb_labels, _, efb_predictions = load_data(args, args.model, args.data, "efb")
        ood_efb_labels, _, ood_efb_predictions = load_data(args, args.model, args.data, "efb", ood=True)
        plot.inv_ecdf_vs_pred_entropy(ood_efb_predictions, "EFB-Laplace", c4, axis=ax)
        plot.inv_ecdf_vs_pred_entropy(efb_predictions, color=c4, linestyle='--', axis=ax)
    except FileNotFoundError:
        print(f"Data for model {args.model} and estimator EFB not available.")
    try:
        inf_labels, _, inf_predictions = load_data(args, args.model, args.data, "inf")
        ood_inf_labels, _, ood_inf_predictions = load_data(args, args.model, args.data, "inf", ood=True)
        plot.inv_ecdf_vs_pred_entropy(ood_inf_predictions, "INF-Laplace", c5, axis=ax)
        plot.inv_ecdf_vs_pred_entropy(inf_predictions, color=c5, linestyle='--', axis=ax)
    except FileNotFoundError:
        print(f"Data for model {args.model} and estimator INF not available.")
    try:
        swag_labels, _, swag_predictions = load_data(args, args.model, args.data, "swag")
        swa_labels, _, swa_predictions = load_data(args, args.model, args.data, "swa")
        ood_swag_labels, _, ood_swag_predictions = load_data(args, args.model, args.data, "swag", ood=True)
        ood_swa_labels, _, ood_swa_predictions = load_data(args, args.model, args.data, "swa", ood=True)
        plot.inv_ecdf_vs_pred_entropy(ood_swa_predictions, "SWA", c6, axis=ax)
        plot.inv_ecdf_vs_pred_entropy(ood_swag_predictions, "SWAG", c7, axis=ax)
        plot.inv_ecdf_vs_pred_entropy(swa_predictions, color=c6, linestyle='--', axis=ax)
        plot.inv_ecdf_vs_pred_entropy(swag_predictions, color=c7, linestyle='--', axis=ax)
    except FileNotFoundError:
        print(f"Data for model {args.model} and estimator SWA/SWAG not available.")

    solid, = ax.plot([], [], c="black", ls='-')
    dashed, = ax.plot([], [], c="black", ls='--')

    lines = plt.legend(fontsize=16, loc="upper right", frameon=False)
    plt.legend([solid, dashed], ["out-of-domain", "in-domain"], fontsize=14, loc="lower left", frameon=False)
    ax.add_artist(lines)

    plt.savefig(args.results_dir + f"/figures/out_of_domain_{args.model}.pdf", format='pdf', dpi=1200)

def out_of_domain_overview(args):
    fig, ax = plt.subplots(figsize=(12, 7), tight_layout=True)

    nets = ['resnet18', 'resnet50', 'resnet152', 'densenet121', 'densenet161']

    for name in nets:
        color = next(ax._get_lines.prop_cycler)['color']
        try:
            if args.estimator in ['swa', 'swag']:
                _, _, predictions = load_data(args, name, args.data, args.estimator)
                _, _, ood_predictions = load_data(args, name, args.data, args.estimator, ood=True)
            elif args.estimator == 'sgd':
                _, predictions, _ = load_data(args, name, args.data, 'kfac')
                _, ood_predictions, _ = load_data(args, name, args.data, 'kfac', ood=True)
            else:
                _, _, predictions = load_data(args, name, args.data, args.estimator)
                _, _, ood_predictions = load_data(args, name, args.data, args.estimator, ood=True)
            plot.inv_ecdf_vs_pred_entropy(ood_predictions, name.capitalize(), color=color, axis=ax)
            plot.inv_ecdf_vs_pred_entropy(predictions, color=color, linestyle='--', axis=ax)
        except FileNotFoundError:
            print(f"Data for model {name} not available.")

    solid, = ax.plot([], [], c="black", ls='-')
    dashed, = ax.plot([], [], c="black", ls='--')

    lines = plt.legend(fontsize=16, loc="upper right", frameon=False)
    plt.legend([solid, dashed], ["out-of-domain", "in-domain"], fontsize=14, loc="lower left", frameon=False)
    ax.add_artist(lines)

    plt.savefig(args.results_dir + f"/figures/out_of_domain_{args.estimator}.pdf", format='pdf', dpi=1200)

def eigenvalues(args):
    print("Loading factors")
    factors_path = os.path.join(args.root_dir, "factors",
                                f"{args.prefix}{args.model}_{args.data}_{args.estimator}{args.suffix}.pth")
    factors = torch.load(factors_path, map_location='cpu')

    filename = f"{args.prefix}{args.model}_{args.data}{args.suffix}"
    fig_path = os.path.join(args.results_dir, args.model, "figures", args.estimator, filename)

    print("Computing eigenvalues")
    eigvals = get_eigenvalues(factors, verbose=True)
    plot.eigenvalue_histogram(eigvals.numpy(), show_stats=args.verbose, path=fig_path + "_eigenvalue_histogram.pdf")

def print_hyperparameters(args):
    hyper_list = list()
    for name in ['resnet18', 'resnet50', 'resnet152',
                 'densenet121', 'densenet161']:
        tmp = [name.capitalize()]
        for est in ['diag', 'kfac', 'efb', 'inf']:
            filename = f"{args.prefix}{name}_{args.data}{args.suffix}"
            results_path = os.path.join(args.results_dir, name, "data", est, filename)
            try:
                norm, scale = np.load(results_path + "_best_params.npy")
                tmp.append(round(norm))
                tmp.append(round(scale))
            except FileNotFoundError:
                pass
        hyper_list.append(tmp)
    print(tabulate.tabulate(hyper_list,
                            headers=['Model', 'DIAG Norm', 'DIAG Scale', 'KFAC Norm', 'KFAC Scale',
                                     'EFB Norm', 'EFB Scale', 'INF Norm', 'INF Scale'], tablefmt='rst',
                            numalign='right', floatfmt=".0f"))

def hyperparameters(args, plot_3d=False, plot_time=True):
    filename = f"{args.prefix}{args.model}_{args.data}_{args.estimator}{args.suffix}"
    if not plot_time:
        results_path = os.path.join(args.results_dir, args.model, "data", args.estimator, args.optimizer, filename)
        try:
            data = np.load(results_path + "_hyperopt_stats.npy", allow_pickle=True).item()
            metrics = ['score', 'acc', 'ent', 'nll', 'ece']
        except FileNotFoundError:
            data = dict()
            metrics = ['score']
        res = skopt.load(results_path + "_hyperopt_dump.pkl")
        data['norm'] = np.array(res.x_iters)[:, 0]
        data['scale'] = np.array(res.x_iters)[:, 1]
        data['score'] = np.array(res.func_vals)

    if plot_3d:
        plot.hyper_results_3d(data)
    elif plot_time:
        fig, ax = plt.subplots(figsize=(12, 7), tight_layout=True)
        c1 = next(ax._get_lines.prop_cycler)['color']
        c2 = next(ax._get_lines.prop_cycler)['color']
        gp_data = list()
        random_data = list()
        for i in range(10):
            random_path = os.path.join(args.results_dir, args.model, "data", args.estimator, 'random', str(i), filename)
            gp_path = os.path.join(args.results_dir, args.model, "data", args.estimator, 'gp', str(i), filename)
            try:
                data = np.load(random_path + f"_hyperopt_stats{'_layer.npy' if args.layer else '.npy'}", allow_pickle=True).item()
                #ax.scatter(np.arange(len(random_data['cost'])), random_data['cost'], c=c1, marker='x')
                random_data.append([np.nanmin(data['cost'][:i + 1]) for i in range(len(data['cost']))])
                #ax.plot(random_data, c=c1, lw=0.5, ls='--')
            except FileNotFoundError:
                print(f"Data for experiment {i} (random) not available.")
            try:
                data = np.load(gp_path + f"_hyperopt_stats{'_layer.npy' if args.layer else '.npy'}", allow_pickle=True).item()
                #ax.scatter(np.arange(len(gp_data['cost'])), gp_data['cost'], c=c2, marker='+')
                gp_data.append([np.nanmin(data['cost'][:i + 1]) for i in range(len(data['cost']))])
                #ax.plot(gp_data, c=c2, lw=0.5, ls='--')
            except FileNotFoundError:
                print(f"Data for experiment {i} (gp) not available.")

        random_data = np.array(random_data)
        random_mean = np.nanmean(random_data, axis=0)
        random_std = np.nanstd(random_data, axis=0)
        ax.plot(random_mean, c=c1, lw=2, label='Random Search')
        plt.fill_between(np.arange(random_mean.shape[0]), random_mean - random_std, random_mean + random_std, color=c1, alpha=0.2)

        gp_data = np.array(gp_data)
        gp_mean = np.nanmean(gp_data, axis=0)
        gp_std = np.nanstd(gp_data, axis=0)
        ax.plot(gp_mean, c=c2, lw=2, label='Bayesian Optimization')
        plt.fill_between(np.arange(gp_mean.shape[0]), gp_mean - gp_std, gp_mean + gp_std, color=c2, alpha=0.2)
        plt.legend(fontsize=16)
        plt.xlabel('Iteration', fontsize=14)
        plt.ylabel('Error + ECE', fontsize=14)
        plt.show()
    else:
        for metric in metrics:
            data[metric] = np.array(data[metric])
            fig_path = results_path.replace("data", "figures") + f"_hyper_results_{metric}.pdf"
            plot.hyper_results(data, metric, annotate=True, path=fig_path)

def adversarial_attack(args):
    for metric in ['ent', 'acc']:
        fig, ax = plt.subplots(figsize=(9, 9), tight_layout=True)
        filename = f"{args.prefix}{args.model}_{args.data}_fgsm{args.suffix}.npz"

        for estimator in ['kfac', 'diag', 'efb', 'inf']:
            results_path = os.path.join(args.results_dir, args.model, "data", estimator, filename)
            try:
                data = np.load(results_path, allow_pickle=True)
                stats, bnn_stats = data['stats'].item(), data['bnn_stats'].item()
                epsilons = stats['eps']
                color = next(ax._get_lines.prop_cycler)['color']

                if estimator == 'kfac':
                    plt.plot(epsilons, stats[metric], color=color, linewidth=3, label='SGD')
                    color = next(ax._get_lines.prop_cycler)['color']
                label = estimator.upper()
                plt.plot(epsilons, bnn_stats[metric], color=color, linewidth=3, label=f"{label}-Laplace")
                ax.spines['top'].set_visible(False)
                ax.spines['right'].set_visible(False)
                ax.grid(linestyle='dashed')
                ax.tick_params(direction='out', labelsize=14, right=False, top=False)
                ax.set_ylabel('Predictive Entropy' if metric == 'ent' else 'Accuracy', fontsize=16)
                ax.set_xlabel('Step size', fontsize=16)
                ax.set_xlim(0, 1)
                ax.legend(fontsize=16)

            except FileNotFoundError:
                print(f"Data for model {args.model} and estimator {estimator.upper()} not available.")
        plt.savefig(args.results_dir + f"/figures/adv_{metric}_{args.model}_{args.data}.pdf", format='pdf', dpi=1200)

def summary(args):
    if args.model == 'lenet5':
        model = lenet5(pretrained=args.data, device=args.device)
    elif args.model == 'resnet18' and args.data != 'imagenet':
        model = resnet18(pretrained=os.path.join(args.root_dir, 'weights', f"{args.model}_{args.data}.pth"),
                         device=args.device)
    else:
        model_class = getattr(torchvision.models, args.model)
        if args.model in ['googlenet', 'inception_v3']:
            model = model_class(pretrained=True, aux_logits=False)
        else:
            model = model_class(pretrained=True)

    module_classes = list()
    for module in model.modules():
        module_class = module.__class__.__name__
        if module_class in ['Linear', 'Conv2d']:
            module_classes.append(module_class)

    diag_list = list()
    kfac_list = list()
    efb_list = list()
    inf_list = list()
    for est in ['diag', 'kfac', 'efb', 'inf']:
        if est == 'diag':
            factors_list = diag_list
        elif est == 'kfac':
            factors_list = kfac_list
        elif est == 'efb':
            factors_list = efb_list
        else:
            factors_list = inf_list

        factors_path = os.path.join(args.root_dir, "factors", f"{args.model}_{args.data}_{est}")
        if est in ["diag", "kfac"]:
            factors = torch.load(factors_path + '.pth', map_location='cpu')
        elif est == 'efb':
            kfac_factors = torch.load(factors_path.replace("efb", "kfac") + '.pth')
            lambdas = torch.load(factors_path + '.pth', map_location='cpu')

            factors = list()
            eigvecs = get_eigenvectors(kfac_factors)

            for eigvec, lambda_ in zip(eigvecs, lambdas):
                factors.append((eigvec[0], eigvec[1], lambda_))
        elif est == 'inf':
            try:
                factors = torch.load(f"{factors_path}{args.rank}.pth", map_location='cpu')
            except FileNotFoundError:
                factors = np.load(factors_path + f"{args.rank}.npz", allow_pickle=True)['sif_list']  # Todo: Remove

        numel_sum = 0
        for index, (cls, factor) in enumerate(zip(module_classes, factors)):
            numel = np.sum([f.numel() for f in factor]).astype(int)
            if est == 'diag':
                factors_list.append([f"{cls} {index}", numel, (numel * 32) / (8 * 1024 ** 2)])
            else:
                factors_list.append([numel, (numel * 32) / (8 * 1024 ** 2)])
            numel_sum += numel
        if est == 'diag':
            factors_list.append(["Total", numel_sum, (numel_sum * 32) / (8 * 1024 ** 2)])
        else:
            factors_list.append([numel_sum, (numel_sum * 32) / (8 * 1024 ** 2)])

    factors_list = np.concatenate([diag_list, kfac_list, efb_list, inf_list], axis=1)

    print(tabulate.tabulate(factors_list, headers=['Layer #', '#Parameters', 'Size (MB)', '#Parameters', 'Size (MB)', '#Parameters', 'Size (MB)', '#Parameters', 'Size (MB)'], floatfmt=".1f",
                            numalign='right', tablefmt='latex'))

def landscapes(args, from2d='x'):
    filename = f"{args.prefix}{args.model}_{args.data}{args.suffix}"
    results_path = os.path.join(args.results_dir, "loss1d" if args.loss1d else "loss2d", filename)

    if args.loss1d:
        if from2d == 'x':
            results_path += "_2dx"
        elif from2d == 'y':
            results_path += "_2dy"
        plot.plot_loss1d(data=np.load(results_path + ".npy"), path=results_path)
    elif args.loss2d:
        plot.plot_surfaces(data=np.load(results_path + ".npy"), show_samples=True, path=results_path)

def main():
    args = setup()
    if args.calibration:
        calibration(args)
    elif args.networks:
        out_of_domain_overview(args)
        calibration_overview(args)
    elif args.ood:
        out_of_domain(args)
    elif args.eigvals:
        eigenvalues(args)
    elif args.hyper:
        hyperparameters(args)
    elif args.fgsm:
        adversarial_attack(args)
    elif args.ecdf:
        ecdf(args)
    elif args.entropy:
        entropy_histogram(args)
    elif args.summary:
        summary(args)
    elif args.landscapes:
        landscapes(args)
    else:
        print_hyperparameters(args)

if __name__ == "__main__":
    main()


from __future__ import (absolute_import, division, print_function)

import os
import os.path
import unittest

from PIL import Image

import imagehash

class TestImageHash(unittest.TestCase):
    @staticmethod
    def get_data_image(fname=None):
        if fname is None:
            fname = 'imagehash.png'
        dname = os.path.abspath(os.path.dirname(__file__))
        target = os.path.join(dname, 'data', fname)
        if not os.path.isfile(target):
            emsg = 'Unknown test image file: {!r}'
            raise ValueError(emsg.format(target))
        return Image.open(target)

    def check_hash_algorithm(self, func, image):
        original_hash = func(image)
        rotate_image = image.rotate(-1)
        rotate_hash = func(rotate_image)
        distance = original_hash - rotate_hash
        emsg = ('slightly rotated image should have '
                'similar hash {} {} {}'.format(original_hash, rotate_hash,
                                               distance))
        self.assertTrue(distance <= 10, emsg)
        rotate_image = image.rotate(-90)
        rotate_hash = func(rotate_image)
        emsg = ('rotated image should have different '
                'hash {} {}'.format(original_hash, rotate_hash))
        self.assertNotEqual(original_hash, rotate_hash, emsg)
        distance = original_hash - rotate_hash
        emsg = ('rotated image should have larger different '
                'hash {} {} {}'.format(original_hash, rotate_hash,
                                       distance))
        self.assertTrue(distance > 10, emsg)

    def check_hash_length(self, func, image, sizes=range(2,21)):
        for hash_size in sizes:
            image_hash = func(image, hash_size=hash_size)
            emsg = 'hash_size={} is not respected'.format(hash_size)
            self.assertEqual(image_hash.hash.size, hash_size**2, emsg)

    def check_hash_stored(self, func, image, sizes=range(2,21)):
        for hash_size in sizes:
            image_hash = func(image, hash_size)
            other_hash = imagehash.hex_to_hash(str(image_hash))
            emsg = 'stringified hash {} != original hash {}'.format(other_hash,
                                                                    image_hash)
            self.assertEqual(image_hash, other_hash, emsg)
            distance = image_hash - other_hash
            emsg = ('unexpected hamming distance {}: original hash {} '
                    '- stringified hash {}'.format(distance, image_hash,
                                                   other_hash))
            self.assertEqual(distance, 0, emsg)

    def check_hash_size(self, func, image, sizes=range(-1,2)):
        for hash_size in sizes:
            with self.assertRaises(ValueError):
                func(image, hash_size)


import json

from app.models import *
def salvar(data):
    try:
        evento = Eventos(
            data['id'] if data['id'] != '' else None,
            data['data'],
            data['descricao'],
            1,
            (session['user_id'] if session['type'] == 'servidor' else None),
            data['privacidade'] if data['privacidade'] != '' else None,
        )
        idEvento = evento.save()
        ServidorEvento.deleteByEvent(idEvento)

        if len(json.loads(data['servidoresVinculados'])) > 0:
            for idServidor in json.loads(data['servidoresVinculados']):
                servidorEvento = ServidorEvento(None, idEvento, idServidor)
                servidorEvento.save()

        return {'success': True}
    except Exception as e:
        return {'success': False, 'error': e}

def delete(id):
    ServidorEvento.deleteByEvent(id)
    evento = Eventos.query.get_or_404(id)
    db.session.delete(evento)
    db.session.commit()
    return {'success': True}


from django.shortcuts import render, redirect

from main.models import *
from django.views.generic import DetailView
from django.http import JsonResponse

def Home(request):
    context = {
        'product':Product.objects.all(),
        'blogs':Blog.objects.all(),
        'foydali':Foydali.objects.all(),
        'client':Clients.objects.all(),
    }
    return render(request, 'index.html', context)

def Blogs(request):
    return render(request, 'blog.html')

def About(request):
    return render(request, 'about.html')

class ProductDetail(DetailView) :
    model = Blog

    template_name = 'blog-details.html'
    context_object_name = 'blog'

def AddToCart(request, id):
    user = request.user

    try:
        shop = Shop.objects.create(client=user, status=0)
    except:
        shop = Shop.objects.create(client = user)
    product = Product.objects.get(id=id)
    if product.discount:
        ShopItem.objects.create(shop=shop, product=product, quantity=1, total=product.discount)
        shop.total += product.discount
    else:
        ShopItem.objects.create(shop=shop, product=product, quantity=1, total=product.price)
        shop.total += product.price
    shop.save()
    return redirect('/')

def Cart(request):
    shop = Shop.objects.filter(status=0)
    products = ShopItem.objects.filter(shop__client=request.user, shop__status=0 )
    context = {
        'products':products,
        'shop':shop[0],
    }
    return render (request, 'cart.html', context)

def CountSavatcha(request):
    count = ShopItem.objects.filter(shop__client=request.user, shop__status=0)
    s = 0
    for c in count:
        s += c.total

    data = {
        'count': count.count(),
        'total': s
    }

    return JsonResponse(data)

def BuyurtmaBerish(request, id):
    shop = Shop.objects.get(id=id)
    shop.status=1
    shop.save()

    return redirect('/')

def DeleteCart(request, id):

    item = ShopItem.objects.get(id=id)
    item.delete()

    return redirect('/cart/')


import logging
import resource
import sys
sys.path.append('../../')

from collections import defaultdict

import numpy as np
import torch
from tqdm import tqdm

import data.mri_data_multicoil as data_batch
from common.args import TestArgs
from common.mytorch import root_sum_of_squares
from common.utils import save_reconstructions
from common.mytorch.tensor_ops import center_crop
from common.train_template import (
    postprocess,
)

logging.basicConfig(level=logging.INFO)
rlimit = resource.getrlimit(resource.RLIMIT_NOFILE)
resource.setrlimit(resource.RLIMIT_NOFILE, (4096, rlimit[1]))

def run_zero_filled_sense(args, data_loader):
    """ Run Adjoint (zero-filled SENSE) reconstruction """
    logging.info('Run zero-filled SENSE reconstruction')
    logging.info(f'Arguments: {args}')
    reconstructions = defaultdict(list)

    with torch.no_grad():
        for sample in tqdm(iter(data_loader)):
            sample = data_batch._read_data(sample)

            rec_x = sample['attrs']['metadata']['rec_x']
            rec_y = sample['attrs']['metadata']['rec_y']

            x = sample['input']

            recons = postprocess(x, (rec_x, rec_y))

            # mask background using background mean value
            if args.mask_bg:
                fg_mask = center_crop(
                    sample['fg_mask'],
                    (rec_x, rec_y),
                ).squeeze(1)
                if args.use_bg_noise_mean:
                    bg_mean = sample['input_rss_mean'].reshape(-1, 1, 1)
                    recons = recons * fg_mask + (1 - fg_mask) * bg_mean
                else:
                    recons = recons * fg_mask

            # renormalize
            norm = sample['attrs']['norm'].numpy()[:, np.newaxis, np.newaxis]
            recons = recons.numpy() * norm

            for bidx in range(recons.shape[0]):
                reconstructions[sample['fname']].append(
                    (sample['slidx'][bidx], recons[bidx])
                )

    reconstructions = {
        fname: np.stack([pred for _, pred in sorted(slice_preds)])
        for fname, slice_preds in reconstructions.items()}

    save_reconstructions(reconstructions, args.out_dir)

def main(args):
    if args.challenge == 'singlecoil':
        raise ValueError('This works only for multicoil challenge!')

    csv_eval = f'{args.csv_path}/multicoil_{args.data_split}.csv'

    data_loader = data_batch.create_eval_data_loaders(args, csv_eval=csv_eval)
    run_zero_filled_sense(args, data_loader)

def create_arg_parser():
    parser = TestArgs()
    parser.add_argument(
        '--use-bg-noise-mean',
        action='store_true',
        help='If set, replace the background by the estimated bg noise mean of the RSS. [Challenge only]',
    )
    return parser

if __name__ == '__main__':
    args = create_arg_parser().parse_args(sys.argv[1:])
    main(args)


import os
import pygame
import importlib
from graphics.obstacles.obstacles import *
from graphics.floor_tiles.floor_tiles import *
DROIDPATH = os.path.join("graphics", "droids")
ITEMPATH = os.path.join("graphics", "items")
DIRECTIONS = {0: "SE", 1: "E", 2: "NE", 3: "N", 4: "NW", 5: "W", 6: "SW", 7: "S"}
BULLET_DIRECTIONS = {0: "NW", 2: "W", 4: "SW", 6: "S", 8: "SE", 10: "E", 12: "NE", 14: "N"}

def load_items():
    temp = importlib.import_module("graphics.item_specs")
    final = {}
    for item in temp.items:
        raw = item["rotation_series"].split("/")
        path = os.path.join(*raw)
        try:
            item["ingame"] = pygame.image.load(os.path.join(ITEMPATH, path, "ingame.png")).convert_alpha()
        except:
            item["ingame"] = None
        item["offset"] = [0, 0]
        try:
            with open(os.path.join(ITEMPATH, path, "ingame.offset")) as f:
                for line in f.readlines():
                    if line.startswith("OffsetX"):
                        item["offset"][0] = int(line.split("=")[1].strip())
                    elif line.startswith("OffsetY"):
                        item["offset"][1] = int(line.split("=")[1].strip())
        except:
            pass
        final[item["type"]] = item
    return final
def load_bullets():
    temp = importlib.import_module("graphics.bullet_specs")
    bullets = {}
    for bullet in temp.bullet_list:
        bullet["images"] = {"SE": [], "E": [], "NE": [], "N": [], "NW": [], "W": [], "SW": [], "S": []}
        for frame in range(bullet.get("phases", 1)):
            for rotation in BULLET_DIRECTIONS.keys():
                image = {}
                string = "iso_bullet" + "_" + bullet["name"] + "_" + str(rotation).zfill(2) + "_" + str(frame + 1).zfill(4)
                image["image"] = pygame.image.load(os.path.join("graphics", "bullets", string + ".png"))
                image["offset"] = [0, 0]
                with open(os.path.join("graphics", "bullets", string + ".offset")) as f:
                    for line in f.readlines():
                        if line.startswith("OffsetX"):
                            image["offset"][0] = int(line.split("=")[1].strip())
                        elif line.startswith("OffsetY"):
                            image["offset"][1] = int(line.split("=")[1].strip())
                bullet["images"][BULLET_DIRECTIONS[rotation]].append(image)
        bullets[bullet["name"]] = bullet
    return bullets
def load_blasts():
    pass
def load_images():
    images = {}
    with open(os.path.join("graphics", "floor_tiles", "atlas.txt")) as atlas:
        floor_atlas = atlas.readlines()
    with open(os.path.join("graphics", "obstacles", "atlas.txt")) as atlas:
        obstacle_atlas = atlas.readlines()
    for line in floor_atlas:
        line = line.split()
        if line[0].startswith("*"):
            image = line[1]
            image_surf = pygame.image.load(os.path.join("graphics", "floor_tiles", image)).convert_alpha()
        else:
            pos = [int(x) for x in line[1:3]]
            size = [int(x) for x in line[3:5]]
            offset = [int(x) for x in line[6:8]]
            images[line[0]] = {"offset": offset, "image": image_surf, "region": [pos, size]}
    for line in obstacle_atlas:
        line = line.split()
        if line[0].startswith("*"):
            image = line[1]
            image_surf = pygame.image.load(os.path.join("graphics", "obstacles", image)).convert_alpha()
        else:
            pos = [int(x) for x in line[1:3]]
            size = [int(x) for x in line[3:5]]
            offset = [int(x) for x in line[6:8]]
            images[line[0]] = {"offset": offset, "image": image_surf, "region": [pos, size]}
    return images
def add_to_list(lst, frame, content):
    length = len(lst)
    if frame >= length:
        lst += [None for x in range(frame - length)] + [content]
    else:
        lst[frame] = content
    return lst
def load_droid_atlas(path):
    images = {
        "N": {"stand": [], "walk": [], "gethit": [], "death": [], "attack": []},
        "S": {"stand": [], "walk": [], "gethit": [], "death": [], "attack": []},
        "E": {"stand": [], "walk": [], "gethit": [], "death": [], "attack": []},
        "W": {"stand": [], "walk": [], "gethit": [], "death": [], "attack": []},
        "NW": {"stand": [], "walk": [], "gethit": [], "death": [], "attack": []},
        "NE": {"stand": [], "walk": [], "gethit": [], "death": [], "attack": []},
        "SW": {"stand": [], "walk": [], "gethit": [], "death": [], "attack": []},
        "SE": {"stand": [], "walk": [], "gethit": [], "death": [], "attack": []}
        }
    folderpath = os.path.split(path)[0]
    with open(path) as f:
        image = None
        image_surf = None
        for line in f.readlines():
            if line.startswith("*"):
                image = line.split()[1]
                image_surf = pygame.image.load(os.path.join(folderpath, image)).convert_alpha()
            else:
                line = line.split()
                rot = DIRECTIONS[int(line[0][11])]
                state = line[0][13:-7]
                frame = int(line[0][-5])
                pos = [int(x) for x in line[1:3]]
                size = [int(x) for x in line[3:5]]
                offset = [int(x) for x in line[6:8]]
                images[rot][state] = add_to_list(images[rot][state], frame, {"offset": offset, "pos": pos, "size": size, "image": image_surf})
    return images
def load_character_graphics():
    graphics = {}
    for path in os.listdir(DROIDPATH):
        atlaspath = os.path.join(DROIDPATH, path, "atlas.txt")
        if os.path.exists(atlaspath):
            graphics[path] = load_droid_atlas(atlaspath)
    return graphics
def load_character_configs():
    configs = {}
    for path in os.listdir(DROIDPATH):
        configpath = os.path.join(DROIDPATH, path, "config.txt")
        if os.path.exists(configpath):
            fps = {}
            with open(configpath) as f:
                for line in f.readlines():
                    line_split = line.split("=")
                    if line_split[0].endswith("fps"):
                        fps[line_split[0][:-4]] = int(line_split[1].strip())
            configs[path] = fps
    return configs
def load_droid_archetypes():
    characters = {}
    character = {}
    current = ""
    with open(os.path.join(DROIDPATH, "droids.txt")) as f:
        for line in f.readlines():
            if line.startswith("** Start of new Robot: **"):
                if current != "":
                    characters[current] = character
                    character = {}
                    current = ""
            elif line.startswith("#") or line.strip() == "":
                pass
            else:
                line_split = line.split("=")
                value = line_split[1].strip()
                if line_split[0] == "droidname":
                    current = value
                elif line_split[0] in ["class", "drop_item_class", "health", "heal_rate", "experience_reward", "hit_probability"]:
                    value = int(float(value))
                elif line_split[0] in ["speed", "aggression_distance", "time_spent_eyeing_player", "gethit_recover_time"]:
                    value = float(value)
                character[line_split[0]] = value
        characters[current] = character
    return characters
def load_characters():
    characters = load_droid_archetypes()
    configs = load_character_configs()
    graphics = load_character_graphics()
    final_characters = {}
    for character in characters.keys():
        temp = characters[character].copy()
        temp["fps"] = configs[temp["graphics_path"]]
        try:
            temp["images"] = graphics[temp["graphics_path"]]
        except:
            pass
        final_characters[character] = temp
    return final_characters
def load_tiles():
    items = load_items()
    bullets = load_bullets()
    images = load_images()
    characters = load_characters()
    for obstacle in obstacles:
        if type(obstacle["images"]) == str:
            obstacle["images"] = images[obstacle["images"]]
        else:
            obstacle["images"] = [images[image] for image in obstacle["images"]]
    for index, tile in enumerate(floor_tiles):
        if type(tile) == str:
            floor_tiles[index] = images[tile]
        else:
            floor_tiles[index]["images"] = [images[image] for image in floor_tiles[index]["images"]]
    return floor_tiles, obstacles, characters, items, bullets


import matplotlib.pyplot as plt
#解决显示中文乱码问题
plt.rcParams["font.sans-serif"]=["SimHei"]
import seaborn as sns
import numpy as np
from PIL import Image
from sklearn.metrics import confusion_matrix,classification_report
from util_data import get_img_infos,split_dataset
sns.set_style("white")

def plot_label_distribution(img_labels):
    #绘制猫和狗的分布
    sns.countplot(img_labels)
    plt.title("cat and dog distribution")
    plt.show()

#用来绘制验证集和测试集的类标分布
def val_pred_and_real_distribution(pred_labels,real_labels):
    label_num_to_name = {0:"cat",1:"dog"}
    #将数字标签转为文字标签
    pred_labels = [label_num_to_name[label] for label in pred_labels]
    real_labels = [label_num_to_name[label] for label in real_labels]
    plt.figure(22)
    #绘制预测结果和真实结果标签的分布情况
    plt.subplot(221)
    sns.countplot(pred_labels)
    plt.title("prediction label distribution")
    plt.subplot(222)
    sns.countplot(real_labels)
    plt.title("real label distribution")
    #绘制预测正确结果和预测错误结果的分布情况
    #计算预测正确的下标位置
    correct_index = np.array(pred_labels)==np.array(real_labels)
    correct = np.array(real_labels)[correct_index]
    plt.subplot(223)
    sns.countplot(correct)
    plt.title("prediction correct label distribution")
    #计算预测错误的下标位置
    error_index = np.array(pred_labels) != np.array(real_labels)
    error = np.array(real_labels)[error_index]
    plt.subplot(224)
    sns.countplot(error)
    plt.title("prediction error label distribution")
    plt.show()

#展示预测正确和错误标签的部分图片
def show_part_image(pred_labels,real_labels,img_paths):
    label_num_to_name = {0:"cat",1:"dog"}
    #获取预测正确的下标
    correct_index = np.array(pred_labels) == np.array(real_labels)
    correct_pred_labels = np.array(pred_labels)[correct_index]
    correct_real_labels = np.array(real_labels)[correct_index]
    correct_img_paths = np.array(img_paths)[correct_index]
    #获取预测错误的下标
    error_index = np.array(pred_labels) != np.array(real_labels)
    error_pred_labels = np.array(pred_labels)[error_index]
    error_real_labels = np.array(real_labels)[error_index]
    error_img_paths = np.array(img_paths)[error_index]
    #展示十张图片上面5张预测正确的图片,下面5张预测错误的图片
    plt.figure(25)
    for i in range(5):
        plt.subplot(2,5,i+1)
        plt.imshow(Image.open(correct_img_paths[i]))
        plt.title("预测:%s\n真实:%s"%(label_num_to_name[correct_pred_labels[i]],
                                           label_num_to_name[correct_real_labels[i]]))
        plt.subplot(2,5,i+6)
        plt.imshow(Image.open(error_img_paths[i]))
        plt.title("预测:%s\n真实:%s"%(label_num_to_name[error_pred_labels[i]],
                                           label_num_to_name[error_real_labels[i]]))
    plt.show()

#绘制混淆矩阵,输出分类情况报告
def classifiction_report_info(pred_labels,real_labels):
    #输出分类结果报告
    classification_info = classification_report(real_labels,pred_labels,target_names=["cat","dog"])
    print(classification_info)
    #展示混淆矩阵
    con_matrix = confusion_matrix(real_labels,pred_labels)
    sns.heatmap(con_matrix,annot=True)
    plt.show()

if __name__ == "__main__":
    img_ids,img_labels,img_paths = get_img_infos("train","txt/train.txt")
    train_dataset,val_dataset = split_dataset(img_ids,img_paths,img_labels)
    print(img_paths)
    plot_label_distribution(train_dataset["img_label"])
    plot_label_distribution(val_dataset["img_label"])


__title__ = "summary document of the model's configuration and outputs"
__author__ = "Manon E. B. Sabot"
__version__ = "1.0 (15.11.2019)"
__email__ = "m.e.b.sabot@gmail.com"

#=======================================================================

import warnings  # ignore these warnings
warnings.filterwarnings("ignore", category=FutureWarning)
warnings.filterwarnings("ignore", category=UserWarning)
warnings.filterwarnings("ignore", category=RuntimeWarning)

# import general modules
import argparse  # read in the user input
import os  # check for files, paths
import sys  # check for files, paths
import numpy as np  # array manipulations, math operators
import numpy.ma as ma  # masked arrays
import pandas as pd  # read/write dataframes, csv files
import docx  # write out a word document
from docx import Document  # write out a word document

# first make sure that modules can be loaded from TractLSM
script_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
sys.path.append(os.path.abspath(os.path.join(script_dir, '..')))

# own modules
from plotting_scripts.plot_utils import find_site_data  # locate
from TractLSM import conv  # unit converter
from TractLSM.Utils import get_main_dir, read_csv  # locate & read

#=======================================================================

def main(projects):

    """
    Main function: writes a word document with information on general
                   analysis about the output generated.

    Arguments:
    ----------
    projects: array
        names of the repository which contain the output to analyse

    Returns:
    --------
    'summary_calibrating_control.docx' in the output directory

    """

    write_word_doc(os.path.join('output', 'summary_calibrating_control.docx'),
                   projects)

    return

#=======================================================================

# ~~~ Other functions are defined here ~~~

def get_best_param(sites, basedir):

    """
    Retrieves the best site-calibrated parameters.

    Arguments:
    ----------
    sites: array
        names of the sites

    basedir: string
        name (path) of the base repository upon which the variation of
        the parameter was performed

    Returns:
    --------
    params: array
        number names associated with the best performing config for each
        site

    """

    try:  # look for "best" param
        fp = open(os.path.join(basedir, 'best.txt'), 'r')
        flines = fp.readlines()
        param = [None] * len(sites)

        for l in flines:

            site = l.split(':')[0].strip()

            if site in sites:
                p = l.split(':')[1].strip()
                param[sites.index(site)] = p

        if not any(param):
            param = None

    except IOError:
        param = None

    return param

def calculate_scores(data):

    """
    Retrieves each of the yearly metrics for all the sites and fluxes and
    projects.

    Arguments:
    ----------
    data: array
        contains all the paths to the input and output data for which these
        need to be compiled

    Returns:
    --------
    NMSE: array
        normalised mean square errors for each of the variables

    MAE: array
        mean absolute error

    SD: array
        standard deviation

    P5: array
        5th percentile

    P95: array
        95th percentile

    """

    # empty arrays to store the performance scores in
    # dims: sites, projects, fluxes, years
    NMSE = np.zeros((data.shape[2], data.shape[1], 2, 2))
    MAE = np.zeros((data.shape[2], data.shape[1], 2, 2))
    SD = np.zeros((data.shape[2], data.shape[1], 2, 2))
    P5 = np.zeros((data.shape[2], data.shape[1], 2, 2))
    P95 = np.zeros((data.shape[2], data.shape[1], 2, 2))

    # loop over sites
    for j in range(data.shape[2]):

        # loop over projects
        for k in range(data.shape[1]):

            # loop over years
            for l in range(data.shape[3]):

                fluxes = ['GPP', 'Qle']

                try:
                    obs, __ = read_csv(data[0, k, j, l])
                    sim, __ = read_csv(data[1, k, j, l])
                    obs.fillna(0., inplace=True)
                    sim.fillna(0., inplace=True)

                    # on a half-hourly basis
                    Dsteps = int(24. / (obs.loc[1, 'hod'] - obs.loc[0, 'hod']))

                    # restrict to subsets of dates
                    year = int(data[0, k, j, l].split('_')[-1]
                               .split('.csv')[0])
                    start = pd.to_datetime(year * 1000 + obs['doy'].iloc[0],
                                           format='%Y%j')

                    if obs['doy'].iloc[-1] > obs['doy'].iloc[0]:
                        end = pd.to_datetime(year * 1000 + obs['doy'].iloc[-1],
                                             format='%Y%j')

                    else:
                        end = pd.to_datetime((year + 1) * 1000 +
                                             obs['doy'].iloc[-1],
                                             format='%Y%j')

                    dates = pd.date_range(start=start, end=end, freq='D')
                    __, iunique = np.unique(dates.month, return_index=True)
                    unique_months = [dates.month[m] for m in sorted(iunique)]

                    # all, restrict dates to growing season
                    dates_2_keep = np.in1d(dates.month, unique_months[3:-2])

                    # restrict to day time and acceptable LAI
                    mask = np.logical_and(obs['PPFD'] > 50.,
                                          obs['LAI'] > 0.001)
                    obs = obs.where(mask).fillna(value=0.)
                    sim = sim.where(mask).fillna(value=0.)

                    # unit conversion
                    obs['Qle'] *= conv.Wpm2_2_mmphlfhr
                    sim['Qle'] = ((sim['E(std)'] + sim['Es(std)']) *
                                  conv.mmolH2Opm2ps_2_mmphlfhr)
                    obs['GPP'] *= conv.umolCpm2ps_2_gCpm2phlfhr
                    sim['GPP'] = sim['A(std)'] * conv.umolCpm2ps_2_gCpm2phlfhr

                    # daily sums
                    obs = obs[fluxes]
                    sim = sim[fluxes]
                    obs = obs.groupby(obs.index // Dsteps * Dsteps).sum()
                    sim = sim.groupby(sim.index // Dsteps * Dsteps).sum()
                    obs.reset_index(inplace=True)
                    sim.reset_index(inplace=True)
                    obs.drop(columns=['index'], inplace=True)
                    sim.drop(columns=['index'], inplace=True)

                    # restricted dates
                    obs = obs[dates_2_keep]
                    sim = sim[dates_2_keep]

                    # deal with missing or negative values
                    mask = np.logical_and(obs > 0., sim > 0.)
                    obs = obs[mask]
                    sim = sim[mask]
                    obs.fillna(0., inplace=True)
                    sim.fillna(0., inplace=True)

                    # loop over An and ET
                    for i in range(len(fluxes)):

                        subobs = obs[fluxes[i]]
                        subsim = sim[fluxes[i]]

                        nmse = np.mean((subsim - subobs) ** 2. /
                                       (np.mean(subsim) * np.mean(subobs)))
                        mae = np.mean(np.abs(subsim - subobs))
                        sd = np.abs(1. - subsim.std() /
                                    np.maximum(1.e-9, subobs.std()))
                        p5 = np.abs(np.percentile(subsim, 5) -
                                    np.percentile(subobs, 5))
                        p95 = np.abs(np.percentile(subsim, 95) -
                                     np.percentile(subobs, 95))

                        if l > 1:
                            NMSE[j, k, i, l-2] = 0.5 * (NMSE[j, k, i, l-2] +
                                                        nmse)
                            MAE[j, k, i, l-2] = 0.5 * (MAE[j, k, i, l-2] + mae)
                            SD[j, k, i, l-2] = 0.5 * (SD[j, k, i, l-2] + sd)
                            P5[j, k, i, l-2] = 0.5 * (P5[j, k, i, l-2] + p5)
                            P95[j, k, i, l-2] = 0.5 * (P95[j, k, i, l-2] + p95)

                        else:
                            NMSE[j, k, i, l] = nmse
                            MAE[j, k, i, l] = mae
                            SD[j, k, i, l] = sd
                            P5[j, k, i, l] = p5
                            P95[j, k, i, l] = p95

                except IOError:
                    pass

    return NMSE, MAE, SD, P5, P95

def write_word_doc(fname, projects):

    """
    Writes the final word document. The order of the tables is as
    follows:

        1. Control calibration NMSEs (close to zero is good)
        2. Control calibration MAEs (close to zero is good)
        3. Control calibration SD metrics (close to zero is good)
        4. Control calibration P5 metrics (close to zero is good)
        5. Control calibration P95 metrics (close to zero is good)
        6. % improvement on the Calibration metrics compared to the
            Control

    Arguments:
    ----------
    fname: string
        name of the summary file to save

    projects: array
        names of the repository which contain the kmax data

    Returns:
    --------
    fname in the directory which harbours TractLSM

    """

    # useful directories
    basedir = get_main_dir()

    while 'src' in basedir:
        basedir = os.path.dirname(get_main_dir())

    Rout = os.path.join(os.path.join(basedir, 'output'), 'projects')

    # declare document
    doc = Document()

    doc.add_heading("Summary of the calibration of the Control", 0)

    description = """This document summarizes:\n
                        general analysis about the output generated
                  """
    p = doc.add_paragraph(description)
    p.add_run('\nThe following projects are accounted for:\n')

    # all file names, dims: idata/odata, projects, sites, years
    data = np.empty((2, len(projects), len(sites), 4), dtype='|S1000')

    tr1 = 0

    for project in projects:

        p.add_run('     %s\n' % (project)).bold = True
        cal = get_best_param(sites, os.path.join(Rout, project))

        if 'g1' in project:
            g1 = cal

        elif 'fw' in project:
            fw = cal

        else:
            cal = ['', ] * len(sites)

        # find all related data
        for i in range(len(sites)):

            tr2 = 0

            for year in [2002, 2003, 2005, 2006]:

                idata, odata = find_site_data(sites[i] + cal[i], year, project)

                try:
                    data[0, tr1, i, tr2] = "%s" % (idata[0])
                    data[1, tr1, i, tr2] = "%s" % (odata[0])

                except Exception:
                    pass

                tr2 += 1

        tr1 += 1

    # performance scores
    scores = (calculate_scores(data))

    track = 0

    for perf in ['NMSE', 'MAE', 'SD', 'P5', 'P95']:

        doc.add_heading('Control optimal %ss' % (perf), level=1)
        score = scores[track]

        t = doc.add_table(rows=len(sites) * 2 + 7, cols=8)
        t.cell(0, 0).text = 'Site Name'
        t.cell(0, 1).text = 'Flux'
        t.cell(0, 2).text = '2002 & 2005'
        t.cell(0, 5).text = '2003 & 2006'
        t.cell(1, 2).text = 'calib g1'
        t.cell(1, 3).text = 'calib fw'
        t.cell(1, 4).text = 'control'
        t.cell(1, 5).text = 'calib g1'
        t.cell(1, 6).text = 'calib fw'
        t.cell(1, 7).text = 'control'

        # rendering of the headers
        t.cell(0, 0).merge(t.cell(1, 0))
        t.cell(0, 2).merge(t.cell(0, 3))
        t.cell(0, 3).merge(t.cell(0, 4))
        t.cell(0, 5).merge(t.cell(0, 6))
        t.cell(0, 6).merge(t.cell(0, 7))

        for i in range(len(sites)):

            site = sites[i]
            t.cell(i * 2 + 2, 0).text = site
            t.cell(i * 2 + 2, 1).text = 'GPP'
            t.cell(i * 2 + 3, 1).text = 'ET'

            for j in range(2):  # GPP, ET

                for k in range(2):  # events

                    if k == 0:
                        bloc = 2

                    else:
                        bloc = 5

                    t.cell(i * 2 + j + 2, bloc).text = \
                        '{0:.2f}'.format(score[i, 0, j, k])
                    t.cell(i * 2 + j + 2, bloc + 1).text = \
                        '{0:.2f}'.format(score[i, 1, j, k])
                    t.cell(i * 2 + j + 2, bloc + 2).text = \
                        '{0:.2f}'.format(score[i, 2, j, k])

        t.cell(len(sites) * 2 + 2, 0).text = 'across sites'
        t.cell(len(sites) * 2 + 2, 1).text = 'GPP'
        t.cell(len(sites) * 2 + 3, 1).text = 'ET'

        for j in range(2):  # GPP, ET

            for k in range(2):  # events

                if k == 0:
                    bloc = 2

                else:
                    bloc = 5

                t.cell(len(sites) * 2 + j + 2, bloc).text = \
                    '{0:.2f}'.format(np.mean(score[:, 0, j, k]))
                t.cell(len(sites) * 2 + j + 2, bloc + 1).text = \
                    '{0:.2f}'.format(np.mean(score[:, 1, j, k]))
                t.cell(len(sites) * 2 + j + 2, bloc + 2).text = \
                    '{0:.2f}'.format(np.mean(score[:, 2, j, k]))

        t.cell((len(sites) + 1) * 2 + 3, 0).text = 'overall'
        t.cell((len(sites) + 1) * 2 + 3, 1).text = 'GPP'
        t.cell((len(sites) + 1) * 2 + 4, 1).text = 'ET'

        for j in range(2):  # GPP, ET

            t.cell((len(sites) + 1) * 2 + j + 3, 2).text = \
                '{0:.2f}'.format(np.mean(score[:, 0, j, :]))
            t.cell((len(sites) + 1) * 2 + j + 3, 3).text = \
                '{0:.2f}'.format(np.mean(score[:, 1, j, :]))
            t.cell((len(sites) + 1) * 2 + j + 3, 4).text = \
                '{0:.2f}'.format(np.mean(score[:, 2, j, :]))

        track += 1

    doc.add_heading('% overall improvement on Control metrics', level=1)

    t = doc.add_table(rows=11, cols=4)
    t.cell(0, 0).text = 'metric'
    t.cell(0, 1).text = 'flux'
    t.cell(0, 2).text = 'g1'
    t.cell(0, 3).text = 'fw'

    track1 = 0
    track2 = 1

    for perf in ['NMSE', 'MAE', 'SD', 'P5', 'P95']:

        score = ma.filled(scores[track1], 0.)  # 0. where masked values

        t.cell(track2, 0).text = perf
        t.cell(track2, 0).merge(t.cell(track2 + 1, 0))

        for j in range(2):  # GPP, ET

            if j == 0:
                t.cell(track2, 1).text = 'GPP'

            else:
                t.cell(track2, 1).text = 'ET'

            ctrl = np.mean(score[:, 2, j, :])
            g1 = np.mean(score[:, 0, j, :])
            g1 = (abs(ctrl) - abs(g1)) / abs(ctrl)
            t.cell(track2, 2).text = '{0:.2f}'.format(100. * g1)
            fw = np.mean(score[:, 1, j, :])
            fw = (abs(ctrl) - abs(fw)) / abs(ctrl)
            t.cell(track2, 3).text = '{0:.2f}'.format(100. * fw)

            track2 += 1

        track1 += 1

    doc.save(fname)

    return

#=======================================================================

if __name__ == "__main__":

    # define the argparse settings to read run set up file
    description = "Plot all the different site fluxes & soil variations for a \
                   given project folder"
    parser = argparse.ArgumentParser(description=description)
    parser.add_argument("project", nargs='+', help='projects where output are')
    args = parser.parse_args()

    projects = []

    for arg in vars(args):

        for attr in getattr(args, arg):

            projects += [attr]

    sites = ['Hyytiala', 'Soroe', 'Loobos', 'Hesse', 'Parco', 'Puechabon',
             'Rocca1', 'Rocca2', 'ElSaler1', 'Espirra']

    main(projects)


import select
import socket
import pyautogui

def main() -> None:
    host = ""
    port = 12345

    # create a TCP/IP socket
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        sock.setblocking(0)
        # bind the socket to the port
        sock.bind((host, port))
        # listen for incoming connections
        sock.listen(5)
        print("Server started...")

        # sockets from which we expect to read
        inputs = [sock]
        outputs = []

        while inputs:
            # wait for at least one of the sockets to be ready for processing
            readable, writable, exceptional = select.select(inputs, outputs, inputs)

            for s in readable:
                if s is sock:
                    conn, addr = s.accept()
                    inputs.append(conn)
                else:
                    data = s.recv(1024)
                    if data:
                        decoded = data.decode()
                        if decoded == 'right':
                            print("right pressed")
                            pyautogui.press('right')
                        elif decoded == 'left':
                            print("left pressed")
                            pyautogui.press('left')
                    else:
                        inputs.remove(s)
                        s.close()

if __name__ == "__main__":
    main()


import torch
from torch import nn

class Generator(nn.Module):
  def __init__(self):
    super(Generator, self).__init__()

    self.fc = nn.Sequential(
      nn.Linear(62, 1024),
      nn.BatchNorm1d(1024),
      nn.ReLU(),
      nn.Linear(1024, 128 * 7 * 7),
      nn.BatchNorm1d(128 * 7 * 7),
      nn.ReLU()
    )

    self.deconv = nn.Sequential(
      nn.ConvTranspose2d(128, 64, kernel_size=4, stride=2, padding=1),
      nn.BatchNorm2d(64),
      nn.ReLU(),
      nn.ConvTranspose2d(64, 1, kernel_size=4, stride=2, padding=1),
      nn.Sigmoid()
    )

  def forward(self, z):
    x = self.fc(z)
    x = x.view(-1, 128, 7, 7)
    x = self.deconv(x)
    return x

class Discriminator(nn.Module):
  def __init__(self):
    super(Discriminator, self).__init__()

    self.conv = nn.Sequential(
      nn.Conv2d(1, 64, kernel_size=4, stride=2, padding=1),
      nn.LeakyReLU(0.2),
      nn.Conv2d(64, 128, kernel_size=4, stride=2, padding=1),
      nn.BatchNorm2d(128),
      nn.LeakyReLU(0.2)
    )

    self.fc = nn.Sequential(
      nn.Linear(128 * 7 * 7, 1024),
      nn.BatchNorm1d(1024),
      nn.LeakyReLU(0.2),
      nn.Linear(1024, 1),
      nn.Sigmoid()
    )

  def forward(self, x):
    h = self.conv(x)
    h = h.view(-1, 128 * 7 * 7)
    h = self.fc(h)
    return h


# coding: utf-8
# last modified:20220824
import time
import serial
import re
import datetime

import numpy as np
# import matplotlib.pyplot as plt
import subprocess

utctime = ''
lat = ''
ulat = ''
lon = ''
ulon = ''
numSv = ''
msl = ''
cogt = ''
cogm = ''
sog = ''
kph = ''
gps_t = 0

def Convert_to_degrees(in_data1, in_data2):
    len_data1 = len(in_data1)
    str_data2 = "%05d" % int(in_data2)
    temp_data = int(in_data1)
    symbol = 1
    if temp_data < 0:
        symbol = -1
    degree = int(temp_data / 100.0)
    str_decimal = str(in_data1[len_data1-2]) + str(in_data1[len_data1-1]) + str(str_data2)
    f_degree = int(str_decimal)/60.0/100000.0
    # print("f_degree:", f_degree)
    if symbol > 0:
        result = degree + f_degree
    else:
        result = degree - f_degree
    return result

gps_time_list = []
pc_time_list = []

def format_time(raw_time):
    dt = datetime.datetime.strptime(raw_time.decode(), ",%H%M%S.%f")
    # return dt.strftime("2023-%m-%d %H:%M:%S")
    return dt.strftime("2023-04-21 %H:%M:%S")

def GPS_read(ser):
    global utctime
    if ser.inWaiting():
        if ser.read(1) == b'G':
            if ser.inWaiting():
                if ser.read(1) == b'N':
                    if ser.inWaiting():
                        choice = ser.read(1)
                        if choice == b'G':
                            if ser.inWaiting():
                                if ser.read(1) == b'G':
                                    if ser.inWaiting():
                                        if ser.read(1) == b'A':
                                            utctime = ser.read(11) # 读取串口数据
                                            # print('utc:')
                                            # print(utctime)

                                            if(utctime[8] == 48):
                                                print('test:')
                                                print(utctime[8])

                                                gps_time_list.append(utctime) #记录gps报告时间
                                                pc_time_list.append(time.time()) #记录电脑时间
                                                print('utctime:', format_time(utctime))

                                                str1 = str(format_time(utctime))     #格式化GPS报告的时间
                                                # str2 = "2022-04-17 12:00:00"

                                                print('set clock:', str1)
                                                #print('2:', str2)
                                                output = subprocess.check_output(["date","-s", str1])  #设置时间
                                            # print(output.decode())
                                                return True

    return False

def main(Ser_name = "/dev/a-gps", period = 300):

    print("begin to set the clock!")
    Baudrate = 115200

    ser = serial.Serial(Ser_name, Baudrate)

    if ser.isOpen():

        print("GPS Serial Opened! Baudrate="+str(Baudrate))
    else:
        print("GPS Serial Open Failed!")

    while True:

        try:
            if(GPS_read(ser)):
                print('good')
                # time.sleep(period)
                time.sleep(0)

        except Exception as e:
            print(time.strftime("%H:%M:%S"), end=' ')
            print('GPS Exceptions!', e)
            time.sleep(10)
        except KeyboardInterrupt:
            ser.close()
            print("GPS serial Close!")

if __name__ == '__main__':
    main()

# print(gps_time_list)
# print(pc_time_list)
# print(len(gps_time_list))

# # 求误差
# errors = []
# for i in range(0, len(gps_time_list)):
#     s = gps_time_list[i].decode("utf-8")
#     gps_t = datetime.datetime.strptime(s, ",%H%M%S.%f") + datetime.timedelta(days=45012,hours = 8)
#     print(gps_t)
#     gps_timestamp = gps_t.timestamp()

#     pc_timestamp = pc_time_list[i]
#     errors.append(gps_timestamp - pc_timestamp)
#     # gps_t = float(str(gps_time_list[i])[3:-1])
#     # print(gps_t)

# print(errors)

# # 存储文件
# import pickle

# with open(Ser_name +'_data1.pickle', 'wb') as f:
#     pickle.dump(errors, f)

# with open('COM5_data.pickle', 'rb') as f:
#     errors_data1 = pickle.load(f)

# with open('COM7_data.pickle', 'rb') as f:
#     errors_data2 = pickle.load(f)

# data = [errors_data1, errors_data2]
# labels = ['module 1', 'module 2']

# # 绘制箱线图
# fig, ax = plt.subplots()
# ax.boxplot(data, labels=labels)
# ax.set_title('Error Boxplot')
# ax.set_xlabel('Error')
# ax.set_ylabel('Value')
# plt.show()


from base64 import decode
from django.urls import resolve, reverse
from recipes.views import category
from .test_recipe_base import RecipeTestBase

class RecipeViewsTest(RecipeTestBase):
    def test_recipe_category_views_function_is_correct(self):
        category_view = resolve(
            reverse('recipes:category', kwargs={'category_id': 1}))
        self.assertIs(category_view.func, category)

    def test_recipe_category_view_return_404_if_no_recipes_found(self):
        response = self.client.get(
            reverse('recipes:category', kwargs={'category_id': 1000}))
        self.assertEqual(response.status_code, 404)

    def test_recipe_category_template_loads_recipes(self):
        needed_title = 'test recipe'
        recipe = self.make_recipe(title=needed_title)
        response = self.client.get(reverse('recipes:category', kwargs={
                                   'category_id': recipe.category_id}))
        self.assertIn(needed_title, response.content.decode('utf-8'))

    def test_recipe_category_template_dont_show_not_published_recipes(self):
        needed_title = 'Test not published recipes'
        recipe = self.make_recipe(title=needed_title, is_published=False)
        response = self.client.get(
            reverse('recipes:category', kwargs={'category_id': recipe.category_id}))
        self.assertNotIn(needed_title, response.content.decode('utf-8'))


from airflow.hooks.postgres_hook import PostgresHook
from airflow.models import BaseOperator
from airflow.utils.decorators import apply_defaults

class DropTableOperator(BaseOperator):

    ui_color = '#076D9F'
    template_fields = ('tables', )

    @apply_defaults
    def __init__(self,
                 schema,
                 tables,
                 redshift_conn_id='redshift',
                 *args,
                 **kwargs):

        super(DropTableOperator, self).__init__(*args, **kwargs)
        self.schema = schema
        self.tables = tables
        self.redshift_conn_id = redshift_conn_id

    def execute(self, context):
        self.redshift_hook = PostgresHook(self.redshift_conn_id)

        for table in self.tables:
            self.log.info(f'Dropping table: {self.schema}.{table}')
            self.redshift_hook.run(
                f'DROP TABLE IF EXISTS {self.schema}.{table}'
            )


from typing import List
import os
import time
from os import listdir
from os.path import isfile, join

class FolderScanner:
    ignore_file_extensions = ['.crdownload', '.tmp']  # this needs to be hardcoded
    stop_scan = False
    max_file_size = 32  # MB

    def __init__(self, download_folder_path: str) -> None:
        self.download_folder_path = download_folder_path

    def check_directory_changes(self) -> str:
        print(f"excluded_file_extensions: {self.ignore_file_extensions}")
        files_in_download_directory = self._scan_directory()
        while True and not self.stop_scan:
            time.sleep(2)
            new_scan = self._scan_directory()
            for new_file in new_scan:
                ignored_file = self._check_if_file_in_ignore_list(new_file)
                if not ignored_file and new_file not in files_in_download_directory:
                    file_size = os.stat(f"{self.download_folder_path}\{new_file}").st_size
                    if file_size == 0:
                        print(f'size of file 0')
                        files_in_download_directory.append(new_file)
                    valid_file_size = int(f"{file_size / float(1 << 20):,.0f}") <= self.max_file_size
                    absolute_file_path = self.download_folder_path + '\\' + new_file
                    if '.part' in new_file and valid_file_size:
                        if self._file_downloaded_from_firefox(new_file) and \
                                files_in_download_directory[-1][:3] == new_file[:3]:
                            print(f"found file downloaded from firefox")
                            return self.download_folder_path + '\\' + files_in_download_directory[-1]
                    elif valid_file_size and file_size > 1 and '.part' not in new_file:
                        return absolute_file_path
                    else:
                        print(f"passing", new_file)

    def _scan_directory(self) -> List:
        """Scan directory & return all file names"""
        directory = [f for f in listdir(self.download_folder_path) if
                     isfile(join(self.download_folder_path, f))]
        return directory

    @classmethod
    def stop_scanning(cls, stop: bool) -> None:
        cls.stop_scan = stop

    @classmethod
    def add_file_ext_to_ignore_list(cls, ext: str) -> None:
        file_extensions = ext.split(' ')
        for file_ext in file_extensions:
            if file_ext not in cls.ignore_file_extensions:
                cls.ignore_file_extensions.append(file_ext)

    def _check_if_file_in_ignore_list(self, file_name: str) -> bool:
        for tmp_file_ext in self.ignore_file_extensions:
            if tmp_file_ext in file_name:
                return True
        return False

    def _file_downloaded_from_firefox(self, file_name: str) -> bool:
        """Firefox create temporary file with .part ending when file is not present
         we can assume file was successfully downloaded"""
        abs_file_path = self.download_folder_path + '\\' + file_name
        for _ in range(20):
            # We can assume file is bigger than 32MB if it hasn't been downloaded in 20 sec
            if not os.path.exists(abs_file_path):
                return True
            time.sleep(1)
        return False


import tkinter as tk
from tkinter import messagebox
import tkinter.ttk as ttk
from datetime import date

root = tk.Tk()
root.title("EDAD")
labdia = ttk.Label(root,text="Dia").grid(row=0,column=0,padx=10,pady=10)
dia =ttk.Entry(root)
dia.grid(row=0,column=1)

labmes = ttk.Label(root,text="Mes").grid(row=1,column=0,padx=10,pady=10)
mes = ttk.Combobox(root, values=("Enero", "Febrero", "Marzo", "Abril", "Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"))
mes.set("Enero")
mes.grid(row=1,column=1)

labyear = ttk.Label(root,text="Anio").grid(row=2,column=0,padx=10,pady=10)
year =ttk.Entry(root)
year.grid(row=2,column=1)

def escribir():
    dicdias={"Enero":(1,31), "Febrero":(2,28), "Marzo":(3,31), "Abril":(4,30),"Mayo":(5,31),"Junio":(6,30),"Julio":(7,31),"Agosto":(8,31),"Septiembre":(9,30),"Octubre":(10,31),"Noviembre":(11,30),"Diciembre":(12,31)}
    try:
        d = int(dia.get())
        m = str(mes.get())
        y = int(year.get())
        today = date.today()
        cumplea=date(y,dicdias[m][0],d)
        if d > dicdias[m][1] or len(str(y)) != 4  or y > today.year:
            raise ("len error")
        edad = today.year - cumplea.year - ((today.month, today.day) < (cumplea.month, cumplea.day))
    except:
        tk.messagebox.showwarning(title="Datos No validos", message="Corrobore dia (DD) y anio (YYYY)")
    ttk.Label(root,text = "Edad: " ).grid(row=3,column=0)
    ttk.Label(root,text = edad ).grid(row=3,column=1,padx=10,pady=10)

tk.Button(root, text="Submit", fg = "black", bg = "gold", font = "Helvetica 20 bold italic",command = escribir).grid(row=3,column=0)

root.mainloop()

#Ejemplo by Lean