from nose.tools import assert_true
from nose.tools import assert_equal

from scipy.sparse import csr_matrix
from scipy.sparse import csc_matrix
from scipy.linalg import eigh
import numpy as np
from numpy.testing import assert_array_almost_equal

from nose.tools import assert_raises
from nose.plugins.skip import SkipTest

from sklearn.manifold.spectral_embedding_ import SpectralEmbedding
from sklearn.manifold.spectral_embedding_ import _graph_is_connected
from sklearn.manifold.spectral_embedding_ import _graph_connected_component
from sklearn.manifold import spectral_embedding
from sklearn.metrics.pairwise import rbf_kernel
from sklearn.metrics import normalized_mutual_info_score
from sklearn.cluster import KMeans
from sklearn.datasets.samples_generator import make_blobs
from sklearn.utils.graph import graph_laplacian
from sklearn.utils.extmath import _deterministic_vector_sign_flip

# non centered, sparse centers to check the
centers = np.array([
    [0.0, 5.0, 0.0, 0.0, 0.0],
    [0.0, 0.0, 4.0, 0.0, 0.0],
    [1.0, 0.0, 0.0, 5.0, 1.0],
])
n_samples = 1000
n_clusters, n_features = centers.shape
S, true_labels = make_blobs(n_samples=n_samples, centers=centers,
                            cluster_std=1., random_state=42)

def _check_with_col_sign_flipping(A, B, tol=0.0):
    """ Check array A and B are equal with possible sign flipping on
    each columns"""
    sign = True
    for column_idx in range(A.shape[1]):
        sign = sign and ((((A[:, column_idx] -
                            B[:, column_idx]) ** 2).mean() <= tol ** 2) or
                         (((A[:, column_idx] +
                            B[:, column_idx]) ** 2).mean() <= tol ** 2))
        if not sign:
            return False
    return True

def test_spectral_embedding_two_components(seed=36):
    # Test spectral embedding with two components
    random_state = np.random.RandomState(seed)
    n_sample = 100
    affinity = np.zeros(shape=[n_sample * 2,
                               n_sample * 2])
    # first component
    affinity[0:n_sample,
             0:n_sample] = np.abs(random_state.randn(n_sample, n_sample)) + 2
    # second component
    affinity[n_sample::,
             n_sample::] = np.abs(random_state.randn(n_sample, n_sample)) + 2

    # Test of internal _graph_connected_component before connection
    component = _graph_connected_component(affinity, 0)
    assert_true(component[:n_sample].all())
    assert_true(not component[n_sample:].any())
    component = _graph_connected_component(affinity, -1)
    assert_true(not component[:n_sample].any())
    assert_true(component[n_sample:].all())

    # connection
    affinity[0, n_sample + 1] = 1
    affinity[n_sample + 1, 0] = 1
    affinity.flat[::2 * n_sample + 1] = 0
    affinity = 0.5 * (affinity + affinity.T)

    true_label = np.zeros(shape=2 * n_sample)
    true_label[0:n_sample] = 1

    se_precomp = SpectralEmbedding(n_components=1, affinity="precomputed",
                                   random_state=np.random.RandomState(seed))
    embedded_coordinate = se_precomp.fit_transform(affinity)
    # Some numpy versions are touchy with types
    embedded_coordinate = \
        se_precomp.fit_transform(affinity.astype(np.float32))
    # thresholding on the first components using 0.
    label_ = np.array(embedded_coordinate.ravel() < 0, dtype="float")
    assert_equal(normalized_mutual_info_score(true_label, label_), 1.0)

def test_spectral_embedding_precomputed_affinity(seed=36):
    # Test spectral embedding with precomputed kernel
    gamma = 1.0
    se_precomp = SpectralEmbedding(n_components=2, affinity="precomputed",
                                   random_state=np.random.RandomState(seed))
    se_rbf = SpectralEmbedding(n_components=2, affinity="rbf",
                               gamma=gamma,
                               random_state=np.random.RandomState(seed))
    embed_precomp = se_precomp.fit_transform(rbf_kernel(S, gamma=gamma))
    embed_rbf = se_rbf.fit_transform(S)
    assert_array_almost_equal(
        se_precomp.affinity_matrix_, se_rbf.affinity_matrix_)
    assert_true(_check_with_col_sign_flipping(embed_precomp, embed_rbf, 0.05))

def test_spectral_embedding_callable_affinity(seed=36):
    # Test spectral embedding with callable affinity
    gamma = 0.9
    kern = rbf_kernel(S, gamma=gamma)
    se_callable = SpectralEmbedding(n_components=2,
                                    affinity=(
                                        lambda x: rbf_kernel(x, gamma=gamma)),
                                    gamma=gamma,
                                    random_state=np.random.RandomState(seed))
    se_rbf = SpectralEmbedding(n_components=2, affinity="rbf",
                               gamma=gamma,
                               random_state=np.random.RandomState(seed))
    embed_rbf = se_rbf.fit_transform(S)
    embed_callable = se_callable.fit_transform(S)
    assert_array_almost_equal(
        se_callable.affinity_matrix_, se_rbf.affinity_matrix_)
    assert_array_almost_equal(kern, se_rbf.affinity_matrix_)
    assert_true(
        _check_with_col_sign_flipping(embed_rbf, embed_callable, 0.05))

def test_spectral_embedding_amg_solver(seed=36):
    # Test spectral embedding with amg solver
    try:
        from pyamg import smoothed_aggregation_solver
    except ImportError:
        raise SkipTest("pyamg not available.")

    se_amg = SpectralEmbedding(n_components=2, affinity="nearest_neighbors",
                               eigen_solver="amg", n_neighbors=5,
                               random_state=np.random.RandomState(seed))
    se_arpack = SpectralEmbedding(n_components=2, affinity="nearest_neighbors",
                                  eigen_solver="arpack", n_neighbors=5,
                                  random_state=np.random.RandomState(seed))
    embed_amg = se_amg.fit_transform(S)
    embed_arpack = se_arpack.fit_transform(S)
    assert_true(_check_with_col_sign_flipping(embed_amg, embed_arpack, 0.05))

def test_pipeline_spectral_clustering(seed=36):
    # Test using pipeline to do spectral clustering
    random_state = np.random.RandomState(seed)
    se_rbf = SpectralEmbedding(n_components=n_clusters,
                               affinity="rbf",
                               random_state=random_state)
    se_knn = SpectralEmbedding(n_components=n_clusters,
                               affinity="nearest_neighbors",
                               n_neighbors=5,
                               random_state=random_state)
    for se in [se_rbf, se_knn]:
        km = KMeans(n_clusters=n_clusters, random_state=random_state)
        km.fit(se.fit_transform(S))
        assert_array_almost_equal(
            normalized_mutual_info_score(
                km.labels_,
                true_labels), 1.0, 2)

def test_spectral_embedding_unknown_eigensolver(seed=36):
    # Test that SpectralClustering fails with an unknown eigensolver
    se = SpectralEmbedding(n_components=1, affinity="precomputed",
                           random_state=np.random.RandomState(seed),
                           eigen_solver="<unknown>")
    assert_raises(ValueError, se.fit, S)

def test_spectral_embedding_unknown_affinity(seed=36):
    # Test that SpectralClustering fails with an unknown affinity type
    se = SpectralEmbedding(n_components=1, affinity="<unknown>",
                           random_state=np.random.RandomState(seed))
    assert_raises(ValueError, se.fit, S)

def test_connectivity(seed=36):
    # Test that graph connectivity test works as expected
    graph = np.array([[1, 0, 0, 0, 0],
                      [0, 1, 1, 0, 0],
                      [0, 1, 1, 1, 0],
                      [0, 0, 1, 1, 1],
                      [0, 0, 0, 1, 1]])
    assert_equal(_graph_is_connected(graph), False)
    assert_equal(_graph_is_connected(csr_matrix(graph)), False)
    assert_equal(_graph_is_connected(csc_matrix(graph)), False)
    graph = np.array([[1, 1, 0, 0, 0],
                      [1, 1, 1, 0, 0],
                      [0, 1, 1, 1, 0],
                      [0, 0, 1, 1, 1],
                      [0, 0, 0, 1, 1]])
    assert_equal(_graph_is_connected(graph), True)
    assert_equal(_graph_is_connected(csr_matrix(graph)), True)
    assert_equal(_graph_is_connected(csc_matrix(graph)), True)

def test_spectral_embedding_deterministic():
    # Test that Spectral Embedding is deterministic
    random_state = np.random.RandomState(36)
    data = random_state.randn(10, 30)
    sims = rbf_kernel(data)
    embedding_1 = spectral_embedding(sims)
    embedding_2 = spectral_embedding(sims)
    assert_array_almost_equal(embedding_1, embedding_2)

def test_spectral_embedding_unnormalized():
    # Test that spectral_embedding is also processing unnormalized laplacian correctly
    random_state = np.random.RandomState(36)
    data = random_state.randn(10, 30)
    sims = rbf_kernel(data)
    n_components = 8
    embedding_1 = spectral_embedding(sims,
                                     norm_laplacian=False,
                                     n_components=n_components,
                                     drop_first=False)

    # Verify using manual computation with dense eigh
    laplacian, dd = graph_laplacian(sims, normed=False, return_diag=True)
    _, diffusion_map = eigh(laplacian)
    embedding_2 = diffusion_map.T[:n_components] * dd
    embedding_2 = _deterministic_vector_sign_flip(embedding_2).T

    assert_array_almost_equal(embedding_1, embedding_2)


"""Example for generating an arbitrary DAG as a dependency map.

This demo uses networkx to generate the graph.

Authors
-------
* MinRK
"""
import networkx as nx
from random import randint, random
from IPython import parallel

def randomwait():
    import time
    from random import random
    time.sleep(random())
    return time.time()

def random_dag(nodes, edges):
    """Generate a random Directed Acyclic Graph (DAG) with a given number of nodes and edges."""
    G = nx.DiGraph()
    for i in range(nodes):
        G.add_node(i)
    while edges > 0:
        a = randint(0,nodes-1)
        b=a
        while b==a:
            b = randint(0,nodes-1)
        G.add_edge(a,b)
        if nx.is_directed_acyclic_graph(G):
            edges -= 1
        else:
            # we closed a loop!
            G.remove_edge(a,b)
    return G

def add_children(G, parent, level, n=2):
    """Add children recursively to a binary tree."""
    if level == 0:
        return
    for i in range(n):
        child = parent+str(i)
        G.add_node(child)
        G.add_edge(parent,child)
        add_children(G, child, level-1, n)

def make_bintree(levels):
    """Make a symmetrical binary tree with @levels"""
    G = nx.DiGraph()
    root = '0'
    G.add_node(root)
    add_children(G, root, levels, 2)
    return G

def submit_jobs(view, G, jobs):
    """Submit jobs via client where G describes the time dependencies."""
    results = {}
    for node in nx.topological_sort(G):
        with view.temp_flags(after=[ results[n] for n in G.predecessors(node) ]):
            results[node] = view.apply(jobs[node])
    return results

def validate_tree(G, results):
    """Validate that jobs executed after their dependencies."""
    for node in G:
        started = results[node].metadata.started
        for parent in G.predecessors(node):
            finished = results[parent].metadata.completed
            assert started > finished, "%s should have happened after %s"%(node, parent)

def main(nodes, edges):
    """Generate a random graph, submit jobs, then validate that the
    dependency order was enforced.
    Finally, plot the graph, with time on the x-axis, and
    in-degree on the y (just for spread).  All arrows must
    point at least slightly to the right if the graph is valid.
    """
    from matplotlib import pyplot as plt
    from matplotlib.dates import date2num
    from matplotlib.cm import gist_rainbow
    print("building DAG")
    G = random_dag(nodes, edges)
    jobs = {}
    pos = {}
    colors = {}
    for node in G:
        jobs[node] = randomwait

    client = parallel.Client()
    view = client.load_balanced_view()
    print("submitting %i tasks with %i dependencies"%(nodes,edges))
    results = submit_jobs(view, G, jobs)
    print("waiting for results")
    view.wait()
    print("done")
    for node in G:
        md = results[node].metadata
        start = date2num(md.started)
        runtime = date2num(md.completed) - start
        pos[node] = (start, runtime)
        colors[node] = md.engine_id
    validate_tree(G, results)
    nx.draw(G, pos, node_list=colors.keys(), node_color=colors.values(), cmap=gist_rainbow,
            with_labels=False)
    x,y = zip(*pos.values())
    xmin,ymin = map(min, (x,y))
    xmax,ymax = map(max, (x,y))
    xscale = xmax-xmin
    yscale = ymax-ymin
    plt.xlim(xmin-xscale*.1,xmax+xscale*.1)
    plt.ylim(ymin-yscale*.1,ymax+yscale*.1)
    return G,results

if __name__ == '__main__':
    from matplotlib import pyplot as plt
    # main(5,10)
    main(32,96)
    plt.show()


#!/usr/bin/env python
# -*- coding: utf-8 -*-

#É adimensional?
adi = False
#É para salvar as figuras(True|False)?
save = True
#Caso seja para salvar, qual é o formato desejado?
formato = 'jpg'
#Caso seja para salvar, qual é o diretório que devo salvar?
dircg = 'fig-sen'
#Caso seja para salvar, qual é o nome do arquivo?
nome = 'r-velo-r-zz'
#Qual título colocar no gráficos?
titulo = ''#'Curva de ZigZag'
titulo2=''
#Qual a cor dos gráficos?
pc = 'k'
r1c = 'b'
r2c = 'y'
r3c = 'r'
#Estilo de linha
ps = '-'
r1s = '-'
r2s = '-'
r3s = '-'

import os

import scipy as sp
import matplotlib.pyplot as plt

from libplot import *

acelhis = sp.genfromtxt('../entrada/padrao/CurvaZigZag/velo.dat')
acelhis2 = sp.genfromtxt('../entrada/r/saida1.1/CurvaZigZag/velo.dat')
acelhis3 = sp.genfromtxt('../entrada/r/saida1.2/CurvaZigZag/velo.dat')
acelhis4 = sp.genfromtxt('../entrada/r/saida1.3/CurvaZigZag/velo.dat')

lemehis = sp.genfromtxt('../entrada/padrao/CurvaZigZag/leme.dat')
lemehis2 = sp.genfromtxt('../entrada/r/saida1.1/CurvaZigZag/leme.dat')
lemehis3 = sp.genfromtxt('../entrada/r/saida1.2/CurvaZigZag/leme.dat')
lemehis4 = sp.genfromtxt('../entrada/r/saida1.3/CurvaZigZag/leme.dat')

axl = [0, 1000, -0.7, 0.7]
axl2 = [0, 1000, -25, 25]#do leme
#Plotando a Curva de Giro
if adi:
    ylabel = r'$t\prime$'
    xacellabel = r'$ r\prime$'
else:
    ylabel = r'$\dot \psi \quad graus/s$'
    xacellabel = r'$t \quad segundos$'

plt.subplot2grid((1,4),(0,0), colspan=3)
#Padrao
plt.plot(acelhis[:, 0],  acelhis[:, 6] * (180/sp.pi),  color = pc, linestyle = ps,
linewidth = 2, label=ur'padrão')

plt.plot(acelhis2[:, 0],  acelhis2[:, 6] * (180/sp.pi),  color = r1c,linestyle = r1s,
linewidth = 2, label=ur'1.1--$r$')

plt.plot(acelhis3[:, 0], acelhis3[:, 6] * (180/sp.pi), color = r2c, linestyle = r2s,
linewidth = 2, label=ur'1.2--$r$')

plt.plot(acelhis4[:, 0], acelhis4[:, 6] * (180/sp.pi), color = r3c, linestyle = r3s,
linewidth = 2, label=ur'1.3--$r$')

plt.title(titulo)
plt.legend(bbox_to_anchor=(1.1, 1), loc=2, borderaxespad=0.)
plt.ylabel(ylabel)
plt.xlabel(xacellabel)
plt.axis(axl)
plt.grid(True)

plt.twinx()
plt.plot(lemehis[:, 0],  lemehis[:, 1] * (180/sp.pi),  color = pc, linestyle = "--",
linewidth = 1, label=ur'leme--padrão')
plt.plot(lemehis2[:, 0],  lemehis2[:, 1] * (180/sp.pi),  color = r1c, linestyle = "--",
linewidth = 1, label=ur'leme--1.1$r$')
plt.plot(lemehis3[:, 0],  lemehis3[:, 1] * (180/sp.pi),  color = r2c, linestyle = "--",
linewidth = 1, label=ur'leme--1.2$r$')
plt.plot(lemehis4[:, 0],  lemehis4[:, 1] * (180/sp.pi),  color = r3c, linestyle = "--",
linewidth = 1, label=ur'leme--1.3$r$')

plt.title(titulo2)
plt.legend(bbox_to_anchor=(1.1, 0), loc=3, borderaxespad=0.)
plt.ylabel(r"$\delta_R$")
plt.axis(axl2)
plt.grid(False)

if save:
    if not os.path.exists(dircg):
        os.makedirs(dircg)
    if os.path.exists(dircg + '/' + nome + '.' + formato):
        os.remove(dircg + '/' + nome + '.' + formato)
    plt.savefig(dircg + '/' + nome + '.' + formato ,  format=formato)
else:
    plt.show()


#!/bin/python
# -*- coding: utf-8 -*-
"""
Database dump CSV-file with lon/lat is converted to a git compatible geojson
format.

Attributes
----------
infile : str
    File path to database dump.
outfile : str
    File path to geojson file.

Notes
-----
Dump has to match geojson keys title, description, lon and lat.

"""

__copyright__ = "ZNES"
__license__ = "GNU Affero General Public License Version 3 (AGPL-3.0)"
__url__ = "https://github.com/openego/data_processing/blob/master/LICENSE"
__author__ = "s3pp"

import pandas as pd
import json
from os.path import expanduser

infile = '~/open_eGo/scenario/modelpowerplants.csv'
outfile = expanduser("")

df = pd.read_csv(infile, sep=";")
features = []
for ix, row in df.iterrows():

        # properties section
        properties = {"title": row['title'],
                      "description": row['description'],
                      "marker-size": "medium",
                      "marker-symbol": "triangle",
                      "stroke": "#555555"}

        # geometry section
        geometry = {"type": "Point",
                    "coordinates": [row['lon'], row['lat']]}

        # concat to feature
        feature = {"type": "Feature",
                   "geometry": geometry,
                   "properties": properties}

        features.append(feature)

feature_collection = {"type": "FeatureCollection",
                      "features": features}

with open(outfile, 'w') as out:
    json.dump(feature_collection, out)


from brian2 import *

from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg

import matplotlib.pyplot as plt

from dataset import ArtificialDataSet

class ReceptiveField:
    # Parameter that used in standard deviation definition
    gamma = 1.5

    def __init__(self, bank_size=10, I_min=0.0, I_max=1.0):
        self.bank_size = bank_size
        self.field_mu = np.array([(I_min + ((2 * i - 2) / 2) * ((I_max - I_min) / (bank_size - 1)))
                                  for i in range(1, bank_size + 1)])
        self.field_sigma = (1.0 / self.gamma) * (I_max - I_min)

    def float_to_membrane_potential(self, input_vector):
        try:
            input_vector = input_vector.reshape((input_vector.shape[0], 1))
        except Exception as exc:
            print("Exception: {0}\nObject shape: {1}".format(repr(exc), input_vector.shape))
            exit(1)

        temp = np.exp(-((input_vector - self.field_mu) ** 2) / (2 * self.field_sigma * self.field_sigma)) / \
               (np.sqrt(2 * np.pi) * self.field_sigma)
        temp += np.exp(-((input_vector - 1 - self.field_mu) ** 2) / (2 * self.field_sigma * self.field_sigma)) / \
                (np.sqrt(2 * np.pi) * self.field_sigma)
        temp += np.exp(-((input_vector + 1 - self.field_mu) ** 2) / (2 * self.field_sigma * self.field_sigma)) / \
                (np.sqrt(2 * np.pi) * self.field_sigma)

        return temp

if __name__ == "__main__":

    prefs.codegen.target = 'numpy'

    np.random.seed(1)
    seed(1)
    np.set_printoptions(suppress=True)

    bank_size = 10
    diff_method = 'euler'

    # inputs = np.random.rand(3)
    # inputs = np.array([0.332, 0.167, 0.946])
    # inputs = np.array([0.013, 0.3401, 0.2196])
    # inputs = np.array([0.829, 0.7452, 0.6728])
    # print(inputs)
    # N = inputs.shape[0] * bank_size
    N = 20
    rf = ReceptiveField(bank_size=bank_size, I_min=0.05, I_max=0.95)
    # potential_input = rf.float_to_membrane_potential(inputs)
    # potential_input = potential_input.flatten()

    # TABLE 1
    # (A) Neuronal parameters, used in (1) and (4)
    time_step = 0.01;
    tau_m = 10.0 * ms;
    tau_m_inh = 5 * ms;
    tau_m_som = 3 * ms
    theta_reset_u = -0.5;
    theta_reset_inh = -0.0;
    theta_reset_som = 0.0
    theta_u = 0.5;
    theta_u_inh = 0.01;
    theta_som = 0.8
    # (B) Synaptic parameters, used in (2) and (3) for different synapse types
    # temporal layer to som layer (u to v)
    tau_r_afferent = 0.2 * ms;
    tau_f_afferent = 1.0 * ms
    # temporal layer (u to inh exc, u to inh inh, inh to u)
    tau_r_exc = 0.4 * ms;
    tau_f_exc = 2.0 * ms;
    tau_r_inh = 0.2 * ms;
    tau_f_inh = 1.0 * ms
    tau_r_inh2u = 1.0 * ms;
    tau_f_inh2u = 5.0 * ms
    # som layer
    tau_r_lateral = 0.1 * ms;
    tau_f_lateral = 0.5 * ms
    # (C) Maximum magnitudes of synaptic connection strength
    w_syn_temporal_to_som_max = 2.2;
    w_syn_u2inh_exc_max = 1.0;
    w_syn_u2inh_inh_max = 1.0;
    w_syn_inh2u_max = 100.0
    w_syn_som_to_som_max = 1.0
    # (D) Neighbourhood parameters, used in (6) and (7), for layer v (som)
    a = 3.0;
    b = 3.0;
    X = 3.0;
    X_ = 3.0
    # (E) Learning parameter, used in (5)
    # A_plus - Max synaptic strength, A_minus - max synaptic weakness; tau_plus, tau_minus - time constant of STDP
    A_plus = 0.0016;
    A_minus = 0.0055;
    tau_plus = 11;
    tau_minus = 10

    # used in (7)
    T = 10.0;
    power_n = 2.0
    # used in (6)
    pi = np.pi
    # size of the self-organizing map
    map_size = 10

    temporal_layer_neuron_equ = '''
        dtime/dt = 1 / ms : 1

        # inhibition connection to u layer

        ds_inh2u/dt = (-s_inh2u)/tau_r_inh2u: 1
        dw_inh2u/dt = (s_inh2u - w_inh2u)/tau_f_inh2u: 1

        # membrane potential of u layer

        dv/dt = (-v + I_ext - w_inh2u) / tau_m: 1
        I_ext : 1
    '''
    inhibition_neuron_equ = '''
            dtime/dt = 1 / ms : 1

            # inhibition connection
            # s_inh - internal variable
            # w_inh - output potential

            ds_inh/dt = (-s_inh)/tau_r_inh: 1
            dw_inh/dt = (s_inh - w_inh)/tau_f_inh: 1

            # excitation connection
            # s_exc - internal variable
            # w_exc - output potential
            ds_exc/dt = (-s_exc)/tau_r_exc: 1
            dw_exc/dt = (s_exc - w_exc)/tau_f_exc: 1

            # diff equation membrane potential of inhibition neuron
            dv/dt = (-v + w_exc - w_inh) / tau_m_inh: 1
        '''
    som_layer_neuron_equ = '''
                dglobal_time/dt = 1 / ms : 1
                dtime/dt = 1 / ms : 1

                # Afferent connection (from temporal layer to som layer)

                ds_afferent/dt = (-s_afferent)/tau_r_afferent: 1
                dw_afferent/dt = (s_afferent - w_afferent)/tau_f_afferent: 1

                # lateral connection

                ds_lateral/dt = (-s_lateral)/tau_r_lateral: 1
                dw_lateral/dt = (s_lateral - w_lateral)/tau_f_lateral: 1

                # membrane potential of u layer

                dv/dt = (-v + w_lateral + w_afferent) / tau_m_som: 1
            '''

    temporal_layer = NeuronGroup(N, temporal_layer_neuron_equ, threshold='v>theta_u', method=diff_method,
                                 reset='''v = theta_reset_u; time = 0''')
    # temporal_layer.I_ext = potential_input

    # inhibition neuron
    inhibition_neuron = NeuronGroup(1, inhibition_neuron_equ, threshold='v>theta_u_inh', method=diff_method,
                                    reset='''v = theta_reset_inh; time = 0''')
    # self-organizing layer
    som_layer = NeuronGroup(map_size * map_size, som_layer_neuron_equ, threshold='v>theta_som', method=diff_method,
                            reset='''v = theta_reset_som; time = 0''')

    # v to inh neuron, excitation connection
    u2inh_excitation = Synapses(temporal_layer, target=inhibition_neuron, method=diff_method,
                                on_pre='''
                                s_exc += w_syn
                                A_pre = (- w_syn) * A_minus * (1 - 1/tau_minus) ** time_post
                                w_syn = clip(w_syn + plasticity * A_pre, 0, w_syn_u2inh_exc_max)
                                ''',
                                on_post='''
                                A_post = exp(-w_syn) * A_plus * (1 - 1/tau_plus) ** time_pre
                                w_syn = clip(w_syn + plasticity * A_post, 0, w_syn_u2inh_exc_max)
                                ''',
                                model='''
                                w_syn : 1 # synaptic weight / synapse efficacy
                                plasticity : boolean (shared)
                                ''')
    u2inh_excitation.connect(i=np.arange(N), j=0)
    u2inh_excitation.w_syn = 'rand() * w_syn_u2inh_exc_max'

    # v to inh neuron, inhibition connection
    u2inh_inhibition = Synapses(temporal_layer, target=inhibition_neuron, method=diff_method,
                                on_pre='''
                                s_inh += w_syn
                                A_pre = (- w_syn) * A_minus * (1 - 1/tau_minus) * time_post
                                w_syn = clip(w_syn + plasticity * A_pre, 0, w_syn_u2inh_inh_max)
                                ''',
                                on_post='''
                                A_post = exp(-w_syn) * A_plus * (1 - 1/tau_plus) * time_pre
                                w_syn = clip(w_syn + plasticity * A_post, 0, w_syn_u2inh_inh_max)
                                ''',
                                model='''
                                w_syn : 1 # synaptic weight / synapse efficacy
                                plasticity : boolean (shared)
                                ''')
    u2inh_inhibition.connect(i=np.arange(N), j=0)
    u2inh_inhibition.w_syn = 'rand() * w_syn_u2inh_inh_max'

    # inh neuron to v, inhibition connection
    inh2u_inhibition = Synapses(inhibition_neuron, target=temporal_layer, method=diff_method,
                                on_pre='''
                                s_inh2u += w_syn
                                A_pre = (- w_syn) * A_minus * (1 - 1/tau_minus) * time_post
                                w_syn = clip(w_syn + plasticity * A_pre, 0, w_syn_inh2u_max)
                                ''',
                                on_post='''
                                A_post = exp(-w_syn) * A_plus * (1 - 1/tau_plus) * time_pre
                                w_syn = clip(w_syn + plasticity * A_post, 0, w_syn_inh2u_max)
                                ''',
                                model='''
                                w_syn : 1 # synaptic weight / synapse efficacy
                                plasticity : boolean (shared)
                                ''')
    inh2u_inhibition.connect(i=0, j=np.arange(N))
    # inh2u_inhibition.w_syn = 'rand() * w_syn_inh2u_max'
    inh2u_inhibition.w_syn = 0.5 * w_syn_inh2u_max
    # som lateral connection
    som_synapse = Synapses(som_layer, target=som_layer, method=diff_method,
                           on_pre='''
                           radius = X - (X - X_)/(1+(2**0.5 - 1)*((global_time/T)**(2 * power_n)))

                           y_pre = floor(i / map_size)
                           x_pre = i - y_pre * map_size

                           y_post = floor(j/map_size)
                           x_post = j - y_post * map_size

                           dist = (x_post - x_pre)**2 + (y_post - y_pre)**2

                           G1 = (1 + a) * exp(- dist/(radius**2)) / (2 * pi * radius**2)
                           G2 = a * exp(- dist/(b * radius)**2) / (2 * pi * (b * radius)**2)

                           w_syn = clip(G1 + G2, 0, w_syn_som_to_som_max)
                           s_lateral += w_syn
                           ''',
                           on_post='''
                           ''',
                           model='''
                           w_syn : 1 # synaptic weight / synapse efficacy
                           ''')
    som_synapse.connect(condition='i!=j')
    # som afferent connection
    temporal_to_som_synapse = Synapses(temporal_layer, target=som_layer, method=diff_method,
                                       on_pre='''
                                       s_afferent += w_syn
                                       A_pre = (- w_syn) * A_minus * (1 - 1/tau_minus) ** time_post
                                       w_syn = clip(w_syn + plasticity * A_pre, 0,  w_syn_temporal_to_som_max)
                                       ''',
                                       on_post='''
                                       A_post = exp(-w_syn) * A_plus * (1 - 1/tau_plus) * time_pre
                                       w_syn = clip(w_syn + plasticity * A_post, 0,  w_syn_temporal_to_som_max)
                                       ''',
                                       model='''
                                       w_syn : 1 # synaptic weight / synapse efficacy
                                       plasticity : boolean (shared)
                                       ''')
    temporal_to_som_synapse.connect()
    temporal_to_som_synapse.w_syn = np.random.randint(low=40000, high=60000, size=N*map_size*map_size) \
                                    * w_syn_temporal_to_som_max / 100000.0

    # Visualization

    som_spike_mon = SpikeMonitor(som_layer)

    u_spike_mon = SpikeMonitor(temporal_layer)
    # u_state_mon_v = StateMonitor(temporal_layer, 'v', record=True)
    # u_state_mon_time = StateMonitor(temporal_layer, 'time', record=True)
    # u_state_mon_w = StateMonitor(temporal_layer, 'w_inh2u', record=True)

    inh_spike_mon = SpikeMonitor(inhibition_neuron)
    # inh_state_mon = StateMonitor(inhibition_neuron, 'v', record=True)
    # w_exc_neu_state = StateMonitor(inhibition_neuron, 'w_exc', record=True)
    # w_inh_neu_state = StateMonitor(inhibition_neuron, 'w_inh', record=True)
    #
    # w_syn_u2inh_exc = StateMonitor(u2inh_excitation, 'w_syn', record=True)

    defaultclock.dt = time_step * ms

    step = 2

    plasticity_state = False

    u2inh_excitation.plasticity = plasticity_state
    u2inh_inhibition.plasticity = plasticity_state
    inh2u_inhibition.plasticity = plasticity_state
    temporal_to_som_synapse.plasticity = True  # plasticity_state

    # simulation_time = 200
    # run(simulation_time * ms, report='text')
    # weight visualization

    # simulation
    simulation_time = 50
    attempts = 5
    dataset = ArtificialDataSet(500, int(N/10))
    dataset = dataset.generate_set()
    np.savetxt('dataset.txt', dataset, delimiter=';')
    plt.scatter(dataset[:, 0], dataset[:, 1], s=5)
    plt.show()

    net_model = Network(collect())
    net_model.store()
    for vector in dataset:
        for it in range(attempts):
            net_model.restore()
            print("Input vector: {0}, attempt: {1}".format(vector, it))
            potential_input = rf.float_to_membrane_potential(vector)
            potential_input = potential_input.flatten()
            temporal_layer.I_ext = potential_input
            net_model.run(simulation_time * ms, report='text')
            net_model.store()

    # visual
    app = QtGui.QApplication([])
    win = pg.GraphicsWindow(title="som")
    win.resize(1000, 600)
    win.setWindowTitle('brain')
    # Enable antialiasing for prettier plots
    pg.setConfigOptions(antialias=True)

    p1 = win.addPlot(title="Region Selection")

    p1.plot(u_spike_mon.t / ms, u_spike_mon.i[:], pen=None, symbol='o',
            symbolPen=None, symbolSize=5, symbolBrush=(255, 255, 255, 255))
    p1.showGrid(x=True, y=True)
    lr = pg.LinearRegionItem([0, simulation_time])
    lr.setZValue(0)
    p1.addItem(lr)
    p2 = win.addPlot(title="Zoom on selected region")
    p2.plot(u_spike_mon.t / ms, u_spike_mon.i[:], pen=None, symbol='o',
            symbolPen=None, symbolSize=5, symbolBrush=(255, 255, 255, 255))
    p2.showGrid(x=True, y=True)
    def updatePlot():
        p2.setXRange(*lr.getRegion(), padding=0)
    def updateRegion():
        lr.setRegion(p2.getViewBox().viewRange()[0])
    lr.sigRegionChanged.connect(updatePlot)
    p2.sigXRangeChanged.connect(updateRegion)
    updatePlot()

    win.nextRow()

    p3 = win.addPlot(title="Region Selection")
    p3.plot(som_spike_mon.t / ms, som_spike_mon.i[:], pen=None, symbol='o',
            symbolPen=None, symbolSize=5, symbolBrush=(255, 255, 255, 255))
    p3.showGrid(x=True, y=True)
    lr1 = pg.LinearRegionItem([0, 10])
    lr1.setZValue(0)
    p3.addItem(lr1)
    p4 = win.addPlot(title="Zoom on selected region")
    p4.plot(som_spike_mon.t / ms, som_spike_mon.i[:], pen=None, symbol='o',
            symbolPen=None, symbolSize=5, symbolBrush=(255, 255, 255, 255))
    p4.showGrid(x=True, y=True)
    def updatePlot2():
        p4.setXRange(*lr1.getRegion(), padding=0)
    def updateRegion2():
        lr1.setRegion(p4.getViewBox().viewRange()[0])
    lr1.sigRegionChanged.connect(updatePlot2)
    p4.sigXRangeChanged.connect(updateRegion2)
    updatePlot2()

    u2som_syn_shape = temporal_to_som_synapse.w_syn[:].shape
    picture = temporal_to_som_synapse.w_syn[:].reshape(N, int(u2som_syn_shape[0] / N))

    np.savetxt('weights.txt', picture, delimiter=';')

    win2 = QtGui.QMainWindow()
    win2.resize(800, 800)
    imv = pg.ImageView()
    win2.setCentralWidget(imv)
    win2.show()
    win2.setWindowTitle("SOM weights")
    imv.setImage(picture)

    # subplot(421)
    # # subplot(111)
    # title("Temporal layer spikes")
    # plot(u_spike_mon.t / ms, u_spike_mon.i, '.k')
    # xlabel('Time (ms)')
    # ylabel('Neuron index')
    # grid(True)
    # xticks(np.arange(0.0, simulation_time + step, step))
    # yticks(np.arange(-1, N + 1, 1))
    #
    # # show()
    #
    # subplot(422)
    # title("Inhibition neuron spikes")
    # plot(inh_spike_mon.t / ms, inh_spike_mon.i, '.k')
    # xlabel('Time (ms)')
    # ylabel('Neuron index')
    # grid(True)
    # xticks(np.arange(0.0, simulation_time + step, step))
    # yticks(np.arange(-1, 1, 1))
    #
    # subplot(423)
    # title("u membrane potential")
    # for item in u_state_mon_v:
    #     plot(u_state_mon_v.t / ms, item.v)
    # # plot(u_state_mon_v.t / ms, u_state_mon_v[0].v)
    # xlabel('Time (ms)')
    # ylabel('Potential')
    # xticks(np.arange(0.0, simulation_time + step, step))
    #
    # subplot(424)
    # title("Inhibition neuron membrane potential")
    # plot(inh_state_mon.t / ms, inh_state_mon[0].v)
    # xlabel('Time (ms)')
    # ylabel('Potential')
    # xticks(np.arange(0.0, simulation_time + step, step))
    #
    # subplot(425)
    # title("Excitation/inhibition interaction")
    # plot(w_exc_neu_state.t / ms, w_exc_neu_state[0].w_exc, w_exc_neu_state.t / ms, w_inh_neu_state[0].w_inh,
    #      w_exc_neu_state.t / ms, w_exc_neu_state[0].w_exc - w_inh_neu_state[0].w_inh)
    # xlabel('Time (ms)')
    # ylabel('Potential')
    # xticks(np.arange(0.0, simulation_time + step, step))
    #
    # subplot(426)
    # title("Inhibition to u potential")
    # plot(u_state_mon_w.t / ms, u_state_mon_w[0].w_inh2u)
    # xlabel('Time (ms)')
    # ylabel('Potential')
    # xticks(np.arange(0.0, simulation_time + step, step))
    #
    # subplot(427)
    # title("Synaptic Weight")
    # for item in w_syn_u2inh_exc:
    #     plot(w_syn_u2inh_exc.t / ms, item.w_syn)
    # xlabel('Time (ms)')
    # ylabel('Potential')
    # xticks(np.arange(0.0, simulation_time + step, step))
    # yticks(np.arange(-0.1, 1.1, 0.1))
    #
    # subplot(428)
    # title("Synaptic time pre spike")
    # for item in u_state_mon_time:
    #     plot(w_syn_u2inh_exc.t / ms, item.time)
    # xlabel('Time (ms)')
    # ylabel('Potential')
    # xticks(np.arange(0.0, simulation_time + step, step))
    #
    # show()
    #
    # # subplot(111)
    # title("Som layer spikes")
    # plot(som_spike_mon.t / ms, som_spike_mon.i, '.k')
    # xlabel('Time (ms)')
    # ylabel('Neuron index')
    # grid(True)
    # xticks(np.arange(0.0, simulation_time + step, step))
    # yticks(np.arange(-1, map_size * map_size + 1, 1))
    #
    # show()

if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()


# -*- encoding: utf-8 -*-

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import six

import io
import os
import tempfile

import pytest

import numpy as np
from matplotlib import checkdep_usetex, cm, rcParams
from matplotlib.backends.backend_pdf import PdfPages
from matplotlib import pyplot as plt
from matplotlib.testing.determinism import (_determinism_source_date_epoch,
                                            _determinism_check)
from matplotlib.testing.decorators import image_comparison
from matplotlib import dviread
from matplotlib.testing.compare import compare_images

import matplotlib as mpl

needs_usetex = pytest.mark.xfail(
    not checkdep_usetex(True),
    reason="This test needs a TeX installation")

@image_comparison(baseline_images=['pdf_use14corefonts'],
                  extensions=['pdf'])
def test_use14corefonts():
    rcParams['pdf.use14corefonts'] = True
    rcParams['font.family'] = 'sans-serif'
    rcParams['font.size'] = 8
    rcParams['font.sans-serif'] = ['Helvetica']
    rcParams['pdf.compression'] = 0

    text = '''A three-line text positioned just above a blue line
and containing some French characters and the euro symbol:
"Merci pépé pour les 10 €"'''

    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    ax.set_title('Test PDF backend with option use14corefonts=True')
    ax.text(0.5, 0.5, text, horizontalalignment='center',
            verticalalignment='bottom',
            fontsize=14)
    ax.axhline(0.5, linewidth=0.5)

def test_type42():
    rcParams['pdf.fonttype'] = 42

    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.plot([1, 2, 3])
    fig.savefig(io.BytesIO())

def test_multipage_pagecount():
    with PdfPages(io.BytesIO()) as pdf:
        assert pdf.get_pagecount() == 0
        fig = plt.figure()
        ax = fig.add_subplot(111)
        ax.plot([1, 2, 3])
        fig.savefig(pdf, format="pdf")
        assert pdf.get_pagecount() == 1
        pdf.savefig()
        assert pdf.get_pagecount() == 2

def test_multipage_keep_empty():
    from matplotlib.backends.backend_pdf import PdfPages
    from tempfile import NamedTemporaryFile
    # test empty pdf files
    # test that an empty pdf is left behind with keep_empty=True (default)
    with NamedTemporaryFile(delete=False) as tmp:
        with PdfPages(tmp) as pdf:
            filename = pdf._file.fh.name
        assert os.path.exists(filename)
    os.remove(filename)
    # test if an empty pdf is deleting itself afterwards with keep_empty=False
    with PdfPages(filename, keep_empty=False) as pdf:
        pass
    assert not os.path.exists(filename)
    # test pdf files with content, they should never be deleted
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.plot([1, 2, 3])
    # test that a non-empty pdf is left behind with keep_empty=True (default)
    with NamedTemporaryFile(delete=False) as tmp:
        with PdfPages(tmp) as pdf:
            filename = pdf._file.fh.name
            pdf.savefig()
        assert os.path.exists(filename)
    os.remove(filename)
    # test that a non-empty pdf is left behind with keep_empty=False
    with NamedTemporaryFile(delete=False) as tmp:
        with PdfPages(tmp, keep_empty=False) as pdf:
            filename = pdf._file.fh.name
            pdf.savefig()
        assert os.path.exists(filename)
    os.remove(filename)

def test_composite_image():
    # Test that figures can be saved with and without combining multiple images
    # (on a single set of axes) into a single composite image.
    X, Y = np.meshgrid(np.arange(-5, 5, 1), np.arange(-5, 5, 1))
    Z = np.sin(Y ** 2)
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    ax.set_xlim(0, 3)
    ax.imshow(Z, extent=[0, 1, 0, 1])
    ax.imshow(Z[::-1], extent=[2, 3, 0, 1])
    plt.rcParams['image.composite_image'] = True
    with PdfPages(io.BytesIO()) as pdf:
        fig.savefig(pdf, format="pdf")
        assert len(pdf._file._images) == 1
    plt.rcParams['image.composite_image'] = False
    with PdfPages(io.BytesIO()) as pdf:
        fig.savefig(pdf, format="pdf")
        assert len(pdf._file._images) == 2

def test_source_date_epoch():
    """Test SOURCE_DATE_EPOCH support for PDF output"""
    _determinism_source_date_epoch("pdf", b"/CreationDate (D:20000101000000Z)")

def test_determinism_plain():
    """Test for reproducible PDF output: simple figure"""
    _determinism_check('', format="pdf")

def test_determinism_images():
    """Test for reproducible PDF output: figure with different images"""
    _determinism_check('i', format="pdf")

def test_determinism_hatches():
    """Test for reproducible PDF output: figure with different hatches"""
    _determinism_check('h', format="pdf")

def test_determinism_markers():
    """Test for reproducible PDF output: figure with different markers"""
    _determinism_check('m', format="pdf")

def test_determinism_all():
    """Test for reproducible PDF output"""
    _determinism_check(format="pdf")

@image_comparison(baseline_images=['hatching_legend'],
                  extensions=['pdf'])
def test_hatching_legend():
    """Test for correct hatching on patches in legend"""
    fig = plt.figure(figsize=(1, 2))

    a = plt.Rectangle([0, 0], 0, 0, facecolor="green", hatch="XXXX")
    b = plt.Rectangle([0, 0], 0, 0, facecolor="blue", hatch="XXXX")

    fig.legend([a, b, a, b], ["", "", "", ""])

@image_comparison(baseline_images=['grayscale_alpha'],
                  extensions=['pdf'])
def test_grayscale_alpha():
    """Masking images with NaN did not work for grayscale images"""
    x, y = np.ogrid[-2:2:.1, -2:2:.1]
    dd = np.exp(-(x**2 + y**2))
    dd[dd < .1] = np.nan
    fig, ax = plt.subplots()
    ax.imshow(dd, interpolation='none', cmap='gray_r')
    ax.set_xticks([])
    ax.set_yticks([])

# This tests tends to hit a TeX cache lock on AppVeyor.
@pytest.mark.flaky(reruns=3)
@needs_usetex
def test_missing_psfont(monkeypatch):
    """An error is raised if a TeX font lacks a Type-1 equivalent"""
    def psfont(*args, **kwargs):
        return dviread.PsFont(texname='texfont', psname='Some Font',
                              effects=None, encoding=None, filename=None)

    monkeypatch.setattr(dviread.PsfontsMap, '__getitem__', psfont)
    rcParams['text.usetex'] = True
    fig, ax = plt.subplots()
    ax.text(0.5, 0.5, 'hello')
    with tempfile.TemporaryFile() as tmpfile, pytest.raises(ValueError):
        fig.savefig(tmpfile, format='pdf')

@pytest.mark.style('default')
def test_pdf_savefig_when_color_is_none(tmpdir):
    fig, ax = plt.subplots()
    plt.axis('off')
    ax.plot(np.sin(np.linspace(-5, 5, 100)), 'v', c='none')
    actual_image = tmpdir.join('figure.pdf')
    expected_image = tmpdir.join('figure.eps')
    fig.savefig(str(actual_image), format='pdf')
    fig.savefig(str(expected_image), format='eps')
    result = compare_images(str(actual_image), str(expected_image), 0)
    assert result is None