コード例 #1
0
ファイル: plot_kivy.py プロジェクト: ptheywood/python-guis
    def build(self):
        data = np.random.random((10, 10))

        # Create the widgets. We need a vertical box to arrange the navigation toolbar
        hbox = BoxLayout()
        vbox = BoxLayout(orientation="vertical")
        label = Label(text="Click on the plot as many times as you want!")

        # Create the figure.
        fig = Figure()
        axes = fig.add_subplot()
        axes.imshow(data)
        canvas = FigureCanvasKivyAgg(fig)
        nav = NavigationToolbar2Kivy(canvas)

        # Add them to a container.
        vbox.add_widget(canvas)
        vbox.add_widget(nav.actionbar)
        hbox.add_widget(label)
        hbox.add_widget(vbox)

        # Add the callback of the canvas.
        canvas.mpl_connect("button_press_event", on_canvas_click)
        canvas.draw()

        # Return the top container. This can be any widget
        return hbox
コード例 #2
0
ファイル: qm_timeline.py プロジェクト: EliLlanos/quantumlabUB
class YoungSlitScreen(Screen):
    slt_number = NumericProperty(0)
    is_source_on = BooleanProperty(False)

    def __init__(self, **kwargs):
        super(YoungSlitScreen, self).__init__(**kwargs)

    def yspseudo_init(self):

        #temps inicial (0, evidentment)
        self.t = 0
        self.source_on = False

        #recinte i discretitzat
        self.dt = 1 / 20
        self.dl = 2 * self.dt
        self.Nx = 301
        self.Ny = 301

        global Nx_inty, Ny_inty

        Nx_inty = self.Nx
        Ny_inty = self.Ny

        #visualització del recinte que apareix a l'App
        self.h_display = int(self.Ny / 3)
        self.w_display = int(2 * self.Nx / 3)

        #variables de l'ona
        self.w = 2 * pi
        self.c = 1.4
        self.amp = 2.5
        self.tau = 2 * pi / self.w
        self.Ntau = int(1 + self.tau / self.dt)
        self.rao = (self.c * self.dt / self.dl)**2

        #variables paret
        self.sgm_max = 0.02615
        self.m = 1.54

        #llistes de l'ona i la paret en el recinte
        self.a = np.zeros((self.Nx, self.Ny, 3))
        self.a2 = np.zeros((self.Nx, self.Ny, self.Ntau))
        self.inty = np.zeros((self.Nx, self.Ny, 3))

        self.sgm = np.zeros((self.Nx, self.Ny))
        self.sgm_wall = np.zeros((self.Nx, self.Ny))
        self.sgm_det = np.zeros((self.Nx, self.Ny))

        #font
        self.s = np.zeros((self.Nx, self.Ny))

        #slits
        self.Nslt = 0
        self.w_slt = 8

        #gruix i posició de les parets
        self.x_wall = int(self.Nx / 4)
        self.w_wall = int(self.Nx / 30)
        self.w_det = int(self.Nx / 3)

        global w_det_ys
        w_det_ys = self.w_det

        self.slit_presence = np.zeros((self.Nx, self.Ny))
        self.slit_presence[self.x_wall, :] = 1

        self.separation = int(self.Ny / 10)

        #coef d'absorció a les parets del detector
        for k in range(self.w_det):
            self.sgm_det[self.Nx-1-k,0+k:self.Ny-1-k]=\
                self.sgm_max*((self.w_det-k)/self.w_det)**self.m
            self.sgm_det[self.x_wall:self.Nx-k,k]=\
                self.sgm_max*((self.w_det-k)/self.w_det)**self.m
            self.sgm_det[self.x_wall:self.Nx-k,self.Ny-1-k]=\
                self.sgm_max*((self.w_det-k)/self.w_det)**self.m

        ##########################PRIMER DIBUIX###################

        #creem la figura recipient del plot imshow
        self.main_fig, self.axs = plt.subplots(2, sharex=True, sharey=True)

        #L'associem amb kivy
        self.main_canvas = FigureCanvasKivyAgg(self.main_fig)
        self.box1.add_widget(self.main_canvas, 1)

        #Plot de l'ona i de l'intensitat
        self.wave_visu = self.axs[0]
        self.inty_visu = self.axs[1]

        self.at = self.a[:, :, 2]
        self.it = self.inty[:, :, 2]

        #Dibuix de les figures
        self.cmap = plt.get_cmap('Reds')
        self.cmap.set_under('k', alpha=0)

        #diagrama d'ones
        self.wave_visu_im=self.wave_visu.imshow(\
            self.at.transpose()[int((self.Ny-self.h_display)/2):\
                                int((self.Ny+self.h_display)/2),
                                0:self.w_display]
               ,vmax=4,vmin=-4,origin='lower',
        extent=(0,int(self.w_display*self.dl),0,int(self.h_display*self.dl)))

        #representació de la paret al diagrama d'ones
        self.wave_slit_im=self.wave_visu.imshow(\
            self.slit_presence.transpose()[int((self.Ny-self.h_display)/2):\
                                int((self.Ny+self.h_display)/2),
                                0:self.w_display]
               ,vmax=1,vmin=0.5,origin='lower',cmap=self.cmap,
        extent=(0,int(self.w_display*self.dl),0,int(self.h_display*self.dl)))

        #diagrama d'intensitat
        self.inty_visu_im=self.inty_visu.imshow(\
            self.it.transpose()[int((self.Ny-self.h_display)/2):\
                                int((self.Ny+self.h_display)/2),
                                0:self.w_display]
               ,vmax=5,origin='lower',cmap='gray',
        extent=(0,int(self.w_display*self.dl),0,int(self.h_display*self.dl)))

        #representació de la paret al diagrama d'intensitat
        self.inty_slit_im=self.inty_visu.imshow(\
            self.slit_presence.transpose()[int((self.Ny-self.h_display)/2):\
                                int((self.Ny+self.h_display)/2),
                                0:self.w_display]
               ,vmax=1,vmin=0.5,origin='lower',cmap=self.cmap,
        extent=(0,int(self.w_display*self.dl),0,int(self.h_display*self.dl)))

        self.main_canvas.draw()

        self.main_canvas.mpl_connect('resize_event', partial(self.resize_kivy))

    def resize_kivy(self, *largs):
        """Aquesta funció és trucada cada cop que la finestra canvia de tamany.
        Cada cop que això passa, les coordenades (en pixels) dels cantons del plot 
        imshow canvien de lloc. Aquests són molt importants sobretot pel joc, per
        tant, cal tenir-nos ben localitzats."""
        #Aquesta funció de matplotlib ens transforma els cantons de coordenades Data
        # a display (pixels)
        self.wave_cantonsnew = self.wave_visu.transData.transform([
            (0, 0), (0, int(self.h_display * self.dl)),
            (int(self.w_display * self.dl), int(self.h_display * self.dl)),
            (int(self.w_display * self.dl), 0)
        ])

        self.inty_cantonsnew = self.inty_visu.transData.transform([
            (0, 0), (0, int(self.h_display * self.dl)),
            (int(self.w_display * self.dl), int(self.h_display * self.dl)),
            (int(self.w_display * self.dl), 0)
        ])

    def ys_schedule_fired(self):
        "Ara, definim l'update, a partir d'aqui farem l'animació"
        self.schedule = Clock.schedule_interval(self.plotysev, self.dt)

    #integral per trapezis, on h és el pas, i f, una llista amb els valors de
    #la funció a inetgrar, és una llista 3D d'una funció 2D amb dependència temps
    #i com que estem integrant en el temps ens retorna una llista 2D
    def trapezis(self, h, f):
        val = (np.sum(f[:, :, 0:-1], axis=2) +
               np.sum(f[:, :, 1:], axis=2)) * h / 2
        return val

    #funció de la font
    def p_s(self, t, amp, w):
        val = amp * np.sin(w * t)
        return val

    #plot young slit evolution
    def plotysev(self, dt):
        k = 2
        if self.source_on == True:
            self.s[1, :] = self.p_s(self.t, self.amp, self.w)

        if self.source_on == False:
            self.s[:, :] = 0
        """càlculs que fa el programa a cada pas"""

        slt_i = np.zeros((self.Nslt + 2), dtype=int)
        slt_f = np.zeros((self.Nslt + 2), dtype=int)
        slt_n = np.linspace(1, self.Nslt, self.Nslt, dtype=int)
        wall_presence = np.zeros((self.Ny), dtype=int)

        if self.Nslt == 2:
            #posicio del final i l'inici de cada escletxa, ara amb separació variable
            slt_i[1]=int(self.Ny/2)-int(self.separation/2)-\
                int(self.w_slt/2)
            slt_i[2]=int(self.Ny/2)+int(self.separation/2)-\
                int(self.w_slt/2)
            slt_f[1]=int(self.Ny/2)-int(self.separation/2)+\
                int(self.w_slt/2)
            slt_f[2]=int(self.Ny/2)+int(self.separation/2)+\
                int(self.w_slt/2)

            slt_f[0] = 0
            slt_f[self.Nslt + 1] = self.Ny
            slt_i[self.Nslt + 1] = self.Ny

        else:
            #posicio del final i l'inici de cada escletxa
            slt_i[1:self.Nslt+1]=int(self.Ny/2)-int(self.h_display/2)-\
                int(self.w_slt/2)+slt_n[:]*int(self.h_display/(1+self.Nslt))
            slt_f[1:self.Nslt+1]=int(self.Ny/2)-int(self.h_display/2)+\
                int(self.w_slt/2)+slt_n[:]*int(self.h_display/(1+self.Nslt))
            slt_f[0] = 0
            slt_f[self.Nslt + 1] = self.Ny
            slt_i[self.Nslt + 1] = self.Ny

        #les escletxes van de splt_i a splt_f-1, en aquests punts no hi ha paret,
        # a slpt_f ja hi ha paret
        for n in range(1, self.Nslt + 2):
            wall_presence[slt_f[n - 1]:slt_i[n]] = 1
            wall_presence[slt_i[n]:slt_f[n]] = 0

        # matriu que, amb el gruix de la paret com a nombre de files, ens diu si
        # hi ha paret o escletxes a cada una de les y(representades en les columnes)
        wall_presence = np.tile(np.array([wall_presence], dtype=int),
                                (self.w_wall, 1))

        #matriu que diu com de "dins" som a la paret
        wall_n = np.linspace(1, self.w_wall, self.w_wall)
        wall_ny = np.tile(
            np.array([wall_n], dtype=int).transpose(), (1, self.Ny))

        #valors de coeficient d'absorció a les parets
        self.sgm_wall[self.x_wall-self.w_wall:self.x_wall,:]=wall_presence[:,:]\
                    *self.sgm_max*((wall_ny[:,:])/self.w_wall)**self.m

        #llista per a l'última capa de la paret, on l'amplitud d'ona és 0
        self.wave_presence = np.ones((self.Nx, self.Ny))
        self.wave_presence[self.x_wall, :] = (1 - wall_presence[0, :])

        self.sgm = self.sgm_wall + self.sgm_det

        #resolució de l'equació d'ones a cada temps a l'interior del recinte
        self.a[1:-1,1:-1,k]=\
        (self.rao*(self.a[2:,1:-1,k-1]+self.a[0:-2,1:-1,k-1]\
        +self.a[1:-1,2:,k-1]+self.a[1:-1,0:-2,k-1]\
        -4*self.a[1:-1,1:-1,k-1])+self.s[1:-1,1:-1]\
        +2*self.a[1:-1,1:-1,k-1]-self.a[1:-1,1:-1,k-2]\
        +self.sgm[1:-1,1:-1]*self.a[1:-1,1:-1,k-2]/(2*self.dt))\
        /(1+self.sgm[1:-1,1:-1]/(2*self.dt))\
        *self.wave_presence[1:-1,1:-1]

        #condicions periòdiques de contorn a les parets superior i inferior
        self.a[1:self.x_wall,0,k]=\
        (self.rao*(self.a[2:self.x_wall+1,0,k-1]+self.a[0:self.x_wall-1,0,k-1]\
        +self.a[1:self.x_wall,1,k-1]+self.a[1:self.x_wall,self.Ny-1,k-1]\
        -4*self.a[1:self.x_wall,0,k-1])+self.s[1:self.x_wall,0]\
        +2*self.a[1:self.x_wall,0,k-1]-self.a[1:self.x_wall,0,k-2]\
        +self.sgm[1:self.x_wall,0]*self.a[1:self.x_wall,0,k-2]/(2*self.dt))\
        /(1+self.sgm[1:self.x_wall,0]/(2*self.dt))\
        *self.wave_presence[1:self.x_wall,0]

        self.a[1:self.x_wall,self.Ny-1,k]=\
        (self.rao*(self.a[2:self.x_wall+1,self.Ny-1,k-1]\
        +self.a[0:self.x_wall-1,self.Ny-1,k-1]\
        +self.a[1:self.x_wall,0,k-1]+self.a[1:self.x_wall,self.Ny-2,k-1]\
        -4*self.a[1:self.x_wall,self.Ny-1,k-1])+self.s[1:self.x_wall,self.Ny-1]\
        +2*self.a[1:self.x_wall,self.Ny-1,k-1]\
        -self.a[1:self.x_wall,self.Ny-1,k-2]\
        +self.sgm[1:self.x_wall,self.Ny-1]\
        *self.a[1:self.x_wall,self.Ny-1,k-2]/(2*self.dt))\
        /(1+self.sgm[1:self.x_wall,self.Ny-1]/(2*self.dt))\
        *self.wave_presence[1:self.x_wall,self.Ny-1]

        #calculs de la intensitat
        self.a2[:, :, :-1] = self.a2[:, :, 1:]
        self.a2[:, :, self.Ntau - 1] = self.a[:, :, k] * self.a[:, :, k]

        self.inty[:, :, k] = self.trapezis(self.dt, self.a2) / self.tau

        #preparació del següent pas
        self.a[:, :, :-1] = self.a[:, :, 1:]
        self.t = self.t + self.dt

        self.slit_presence = 1 - self.wave_presence
        """Representació a cada pas"""

        #eliminar l'anterior
        self.wave_visu_im.remove()
        self.wave_slit_im.remove()
        self.inty_visu_im.remove()
        self.inty_slit_im.remove()

        #Posar el nou
        self.at = self.a[:, :, 2]
        self.it = self.inty[:, :, 2]

        global intensitat_llum
        intensitat_llum = self.it

        #diagrama d'ones
        self.wave_visu_im=self.wave_visu.imshow(\
            self.at.transpose()[int((self.Ny-self.h_display)/2):\
                                int((self.Ny+self.h_display)/2),
                                0:self.w_display]
               ,vmax=4,vmin=-4,origin='lower',
        extent=(0,int(self.w_display*self.dl),0,int(self.h_display*self.dl)))

        self.wave_slit_im=self.wave_visu.imshow(\
            self.slit_presence.transpose()[int((self.Ny-self.h_display)/2):\
                                int((self.Ny+self.h_display)/2),
                                0:self.w_display]
               ,vmax=1,vmin=0.5,origin='lower',cmap=self.cmap,
        extent=(0,int(self.w_display*self.dl),0,int(self.h_display*self.dl)))

        #diagrama d'intensitat
        self.inty_visu_im=self.inty_visu.imshow(\
            self.it.transpose()[int((self.Ny-self.h_display)/2):\
                                int((self.Ny+self.h_display)/2),
                                0:self.w_display]
               ,vmax=5,origin='lower',cmap='gray',
        extent=(0,int(self.w_display*self.dl),0,int(self.h_display*self.dl)))

        self.inty_slit_im=self.inty_visu.imshow(\
            self.slit_presence.transpose()[int((self.Ny-self.h_display)/2):\
                                int((self.Ny+self.h_display)/2),
                                0:self.w_display]
               ,vmax=1,vmin=0.5,origin='lower',cmap=self.cmap,
        extent=(0,int(self.w_display*self.dl),0,int(self.h_display*self.dl)))

        #I utilitzar-lo
        self.main_canvas.draw()

    def ys_schedule_cancel(self):
        self.schedule.cancel()

    def add_slit(self):
        if self.Nslt < 5:
            self.Nslt += 1
        else:
            pass

    def remove_slit(self):
        if self.Nslt > 0:
            self.Nslt -= 1
        else:
            pass

    def inc_slt_width(self):
        if (self.Nslt * self.w_slt) < self.h_display:
            self.w_slt += 2
        else:
            pass

    def dec_slt_width(self):
        if self.w_slt > 0:
            self.w_slt -= 2
        else:
            pass

    def change_source_state(self):
        self.t = 0
        if self.source_on == False:
            self.source_on = True
        else:
            self.source_on = False

    def clear_waves(self):
        self.a = np.zeros((self.Nx, self.Ny, 3))

    def inc_separation(self):
        if (self.Nslt * self.w_slt + self.separation) < self.h_display:
            self.separation += 2
        else:
            pass

    def dec_separation(self):
        if self.separation > 0:
            self.separation -= 2
        else:
            pass
コード例 #3
0
ファイル: Paquetg.py プロジェクト: marinaristol/quantumlabUB
class PaquetScreen(Screen):
    "Això és la part més important de la app. Introduïrem la pantalla inicial"

    #Les propietats s'han de definir a nivell de classe (millor). Per tant,
    #les definim aquí.
    quadrat = ObjectProperty(None)
    position = ListProperty(None)

    def __init__(self, **kwargs):
        "Unim la clase amb la paraula self"
        super(PaquetScreen, self).__init__(**kwargs)
        #Aquesta linia uneix keyboard amb request keyboard
        self._keyboard = Window.request_keyboard(self._keyboard_closed, self)

        #self._keyboard.bind(on_key_down=self._on_keyboard_down)

    def gpseudo_init(self):

        "Iniciem el primer dibuix de l'aplicació"

        #Variables globals...
        global Vvec, avec, cvec, psi0, normavec, mode

        ################### PARAMETRES DE LA CAIXA,DISCRETITZAT,PARTICULA########
        self.L = 3
        self.xa = -self.L
        self.xb = self.L

        #Discretitzat
        self.tb = 0.1
        self.ta = 0
        self.dx = 0.05
        self.dt = 0.02
        self.Nx = np.int((2 * self.L) / self.dx)

        #particula i constants físiques
        self.m = 1
        self.hbar = 1
        self.t_total = 0.
        self.x0 = 0.
        self.y0 = 0.
        self.px = 0
        self.py = 0

        #Comptador de moments
        self.i = 0
        #parametre del discretitzat
        self.r = (self.dt / (4 * (self.dx**2))) * (self.hbar / self.m)

        #Canvia el text del interior de la caixa 'parameters' amb els parametr
        #es inicials escollits
        self.box3.dxchange.text = "dx={}".format(self.dx)
        self.box3.longitudchange.text = "L={}".format(self.L)
        self.box3.dtchange.text = "dt={}".format(self.dt)

        #################### PARAMETRES NECESSARIS PER EFECTUAR ELS CALCULS######

        #################### POTENCIALS

        #Potencial estandar(mode=0)
        self.Vvecestandar = np.array([[
            ck.Vharm(self.xa + i * self.dx, self.xa + j * self.dx, self.xb,
                     self.xb) for i in range(self.Nx + 1)
        ] for j in range(self.Nx + 1)],
                                     dtype=np.float64)

        #Potencial slit(mode=1)
        self.yposslitd = np.int(self.Nx * (4.75 / 10))
        self.yposslitu = np.int(self.Nx * (5.25 / 10))
        self.xposslit = np.int(self.Nx / 3)
        self.x0slit = self.L / 2
        self.y0slit = 0.
        self.Vvecslit = np.copy(self.Vvecestandar)

        self.Vvecslit[0:self.yposslitd, self.xposslit] = 100000

        self.Vvecslit[self.yposslitu:self.Nx, self.xposslit] = 100000

        ##################### PAQUETS

        #Paquet propi del mode estandar
        self.psiestandar = np.array([[
            ck.psi0f(-self.L + i * self.dx, -self.L + j * self.dx, 0.25,
                     self.px, self.py, self.x0, self.y0)
            for i in range(self.Nx + 1)
        ] for j in range(self.Nx + 1)])  #dtype=np.complex128)

        #Paquet propi del mode slit
        self.psislit = np.array([[
            ck.psi0f(-self.L + i * self.dx, -self.L + j * self.dx, 0.25,
                     self.px, self.py, self.x0slit, self.y0slit)
            for i in range(self.Nx + 1)
        ] for j in range(self.Nx + 1)])

        ##################### MODES

        #mode: 0, estandard
        #      1,slit
        #      2,disparo(encara no està fet)
        #definm el mode inicial tal que:

        self.Vvec = self.Vvecestandar
        self.psi0 = self.psiestandar
        #Ens indica en quin mode estem
        self.mode = 0

        #Per últim, construïm les matrius molt importants per efectuar els càlculs.
        self.avec, self.cvec = ck.ac(self.r, self.Vvec, self.Nx)

        ##########################PRIMER CÀLCUL ENERGIA#####

        #Calculem la matriu densitat inicial
        self.normavec = ck.norma(self.psi0, self.Nx)

        #Calculem moments i energia inicials i els posem al lloc corresponent
        self.norma0 = ck.trapezis(self.xa, self.xb, self.dx,
                                  np.copy(self.normavec))
        self.energy0 = ck.Ham(self.xa, self.xb, self.dx, np.copy(self.psi0))
        self.box3.normachange.text = 'Norma={0:.3f}'.format(self.norma0)
        self.box3.energychange.text = 'Energia={0:.3f}'.format(self.energy0)

        ##########################PRIMER DIBUIX###################

        #creem la figura recipient del plot imshow
        self.main_fig = plt.figure()
        #L'associem amb kivy
        self.main_canvas = FigureCanvasKivyAgg(self.main_fig)
        self.box1.add_widget(self.main_canvas, 1)
        #Plot principal
        self.visu = plt.axes()
        self.visu_im = self.visu.imshow(self.normavec,
                                        origin={'lower'},
                                        extent=(-self.L, self.L, -self.L,
                                                self.L))

        #Posició de la figura
        self.visu.set_position([0, 0.15, 0.8, 0.8])

        #Dibuixem tot lo dit

        self.main_canvas.draw()

        ##################################MATPLOTLIB EVENTS/RESIZING
        #self.main_canvas.mpl_connect('motion_notify_event', motionnotify)

        #Conectem l'event resize de matplotlib amb la funció resize_kivy.
        #Aquesta útlima ens permet saber on estan els cantons de la caixa en
        #coordenades de pixels de la finestra en un primer instant (ja que quan
        # kivy obre matplotlib per primer cop fa ja un resize), i tambe posteriorment,
        # cada cop que fem el resize. Això ens podria ser útil en algún moment.

        self.main_canvas.mpl_connect('resize_event', resize)
        self.main_canvas.mpl_connect('resize_event', partial(self.resize_kivy))

        ################################POTENCIAL MODE/Widget de dibuix

        self.setcordpress = np.array([])
        self.setcordrelease = np.array([])
        self.paint = MyPaintWidget()
        #No pinta a no ser que estigui activat.
        self.paint.pause_paint = True
        self.box1.add_widget(self.paint)

        ###############################PROPIETATS DEL QUADRAT AMB EL QUE JUGUEM
        self.quadrat.pos = [800, 800]
        self.play_game = False

        ###################################BUTONS DE LA CAIXA 2###################
        #Aquests butons varian el menu principal del joc

        #Aquest activa la funció que activa,atura, o reseteja el calcul
        self.box2.add_widget(
            Button(text='Play', on_press=partial(self.compute)))
        self.box2.add_widget(Button(text='Pause',
                                    on_press=partial(self.pause)))
        self.box2.add_widget(Button(text='Reset',
                                    on_press=partial(self.reset)))
        self.box2.add_widget(
            Button(text='Standard', on_press=partial(self.standard)))
        self.box2.add_widget(Button(text='Slit', on_press=partial(self.slit)))
        self.box2.add_widget(Button(text='Game',
                                    on_press=partial(self.gameon)))

        #####################################PAUSESTATE
        self.pause_state = True

    ##Ara venen tot el seguït de funcions que utilitzarem conjuntament amb els
    #parametres definits a g_init

    ##############################RESIZING############################
    #1.Resize_kivy

    #Funcions que s'ocupen del tema resize:
    def resize_kivy(self, *largs):
        """Aquesta funció és trucada cada cop que la finestra canvia de tamany.
        Cada cop que això passa, les coordenades (en pixels) dels cantons del plot 
        imshow canvien de lloc. Aquests són molt importants sobretot pel joc, per
        tant, cal tenir-nos ben localitzats."""

        #Aquesta funció de matplotlib ens transforma els cantons de coordenades Data
        # a display (pixels)
        self.cantonsnew = self.visu.transData.transform([(-3, -3), (-3, 3),
                                                         (3, 3), (3, -3)])

        print(self.cantonsnew)

    ################################FUNCIONS DE CALCUL/FLUX##################
    #1.g_schedule_fired
    #2.plotpsiev
    #3.compute(play)
    #4.pause
    #5.reset

    def g_schedule_fired(self):
        "Ara, definim l'update, a partir d'aqui farem l'animació"
        self.schedule = Clock.schedule_interval(self.plotpsiev, 1 / 60.)

    def plotpsiev(self, dt):
        "Update function that updates psi plot"

        if self.pause_state == False:
            #Primer de tot, representem el primer frame

            if (self.i) == 0:
                self.compute_parameters()
            #Animation
            #Lanimació consisteix en elimanr primer el que teniem abans
            self.normavec = ck.norma(self.psi0, self.Nx)
            self.visu_im.remove()
            #Posar el nou
            self.visu_im = self.visu.imshow(self.normavec,
                                            origin={'lower'},
                                            extent=(-self.L, self.L, -self.L,
                                                    self.L))
            #I utilitzar-lo
            self.main_canvas.draw()
            #CALCUL
            #Tot següit fem el càlcul del següent step
            self.psi0 = ck.Crannk_stepm(self.psi0, self.avec, self.cvec,
                                        self.r, self.Vvec, self.dt, self.Nx,
                                        self.i)

            #Canviem el temps
            self.t_total = self.t_total + (self.dt) / 2.
            self.box3.tempschange.text = 'temps={0:.3f}'.format(self.t_total)

            #Videojoc, coses del  videojoc
            if self.play_game == True:
                self.maxvalue = np.amax(self.normavec)
                self.llindar = self.maxvalue / 20.

                if self.normavec[self.pos_discret[0],
                                 self.pos_discret[1]] > self.llindar:
                    print('Touched')

            #Cada 31 pasos de temps calculem el temps:

            self.i += 1

    def compute(self, *largs):
        """Quan es clica el butó play, s'activa aquesta funció, que activa
        el calcul"""

        self.pause_state = False

    def pause(self, *largs):
        """Aquesta funció para el càlcul del joc"""
        self.pause_state = True

    def reset(self, *largs):
        """Aquesta funció reseteja el paquet i el potencial inicials. Segons el
        mode inicial en el que ens trobem, es resetejara un o l altre."""
        if self.pause_state == True:
            #Segons el mode, reseteja un potencial o un paquet diferent
            if self.mode == 0:
                self.psi0 = self.psiestandar
                self.Vvec = self.Vvecestandar
            if self.mode == 1:
                self.psi0 = self.psislit
                self.Vvec = self.Vvecslit

            #Parametres que s'han de tornar a resetejar
            self.i = 0
            self.px = 0
            self.py = 0
            self.t_toal = 0.

            #Rseteja la imatge

            self.normavec = ck.norma(self.psi0, self.Nx)
            self.visu_im.remove()
            self.visu_im = self.visu.imshow(self.normavec,
                                            origin={'lower'},
                                            extent=(-self.L, self.L, -self.L,
                                                    self.L))

            self.main_canvas.draw()

            #Canviem els parametre en pantalla tambe

            self.box3.tempschange.text = 'temps=0.'
            self.box3.pxchange.text = 'px=0'
            self.box3.pychange.text = 'py=0'

    #####################################CHANGE PARAMETERs##################
    #Fucnions que s'encarregar del canvi efectiu dels parametres
    #1.changep
    def changep(self, add_px, add_py, *largs):
        """Funció que respon als buto + i - que varia el moment inicial del paquet.
        Per que aquest canvi sigui efectiu, hem de canviar tambe el propi paquet."""
        #if selfpause==True
        #Canvi el moment en pantalla
        self.px += add_px
        self.py += add_py
        print(self.px, self.py)

        self.box3.pxchange.text = 'px={}'.format(self.px)
        self.box3.pychange.text = 'py={}'.format(self.py)

        #Canvi del moment efectiu
        if self.mode == 0:
            self.psi0 = np.array([[
                ck.psi0f(-self.L + i * self.dx, -self.L + j * self.dx, 0.25,
                         self.px, self.py, 0., 0.) for i in range(self.Nx + 1)
            ] for j in range(self.Nx + 1)])
        if self.mode == 1:
            self.psi0 = np.array([[
                ck.psi0f(-self.L + i * self.dx, -self.L + j * self.dx, 0.25,
                         self.px, self.py, self.x0slit, self.y0slit)
                for i in range(self.Nx + 1)
            ] for j in range(self.Nx + 1)])

    ################################# POTENCIAL MODE #########################
    #Aquestes funcions juntament amb el widget MyPaintWidget porten la posibilitat
    #de poder dibuixar un potencial.
    #1.editorfun(start)
    #2.editorstop(stop)
    #3.Activatepaint(pinta només si self.paint.pause_paint==False)
    #4.Potpress(apunta les coordenades on es pren el potencial)
    #5.Potrelease(apunta les coordenades on es solta el potencial)
    #6.modifypot(Agafa aquests dos punts i els ajunta, tot creaunt un potencial
    # infinit al mig.
    #7.clear (reseteja el potencial que s'hagui dibuixat, amb tot el que implica)

    def editorfun(self, *largs):
        """Aquesta funció es l'encarregada d'activar el mode editor. Activa
        l'event de matplotlib que detecta la entrada al propi plot o la sortida,
        i l'enllaça amb la funció activatepaint"""

        #Controla que només es pogui dibuixar dins la figura
        self.cidactivate = self.main_canvas.mpl_connect(
            'axes_enter_event', partial(self.activatepaint, 1))
        self.ciddesactivate = self.main_canvas.mpl_connect(
            'axes_leave_event', partial(self.activatepaint, 0))

    def editorstop(self, *largs):
        """Aquesta funció desactiva totes les conexions activades a editorfun,
        i per tant, desactiva el mode editor"""
        self.main_canvas.mpl_disconnect(self.cidactivate)
        self.main_canvas.mpl_disconnect(self.ciddesactivate)

    def activatepaint(self, n, *largs):
        """Aquesta funció s'encarrega d'activar el widget Paint(que dona la
        capactiat de pintar en pantalla, només quan el cursor està dins del
        plot). També activa quatre funcions i les conecta amb les accions 
        d'apretar i soltar el click dret del mouse per, d'aquesta manera,
        enregistar on s'ha apretat."""

        if n == 1:

            self.paint.pause_paint = False
            self.cid1 = self.main_canvas.mpl_connect('button_press_event',
                                                     press)
            self.cid2 = self.main_canvas.mpl_connect('button_press_event',
                                                     partial(self.potpress))
            self.cid3 = self.main_canvas.mpl_connect('button_release_event',
                                                     release)
            self.cid4 = self.main_canvas.mpl_connect('button_release_event',
                                                     partial(self.potrelease))

            print('painting')

        else:
            self.paint.pause_paint = True
            self.main_canvas.mpl_disconnect(self.cid1)
            self.main_canvas.mpl_disconnect(self.cid2)
            self.main_canvas.mpl_disconnect(self.cid3)
            self.main_canvas.mpl_disconnect(self.cid4)

    def potpress(self, *largs):
        """Funció que s'encarrega de guardar en coordenades de data el lloc
        on s'ha apretat al plot"""
        self.setcordpress = np.append(self.setcordpress, cordpress)
        print(self.setcordpress)

    def potrelease(self, *largs):
        """Funció que s'encarrega de guardar en coordenades de data el lloc
        on s'ha soltat al plot."""
        self.setcordrelease = np.append(self.setcordrelease, cordrelease)
        print(self.setcordrelease)

    def modifypot(self, *largs):
        """Aquesta funció s'aplica quan es clika el buto apply. Durant el
        període que s'ha dibuixat, totes les lineas de potencial s'han en-
        registrat a les variables self.csetcorpress i setcordreleas. Aquestes
        estan en coordenades de self. data i les hem de passar al discretitzat."""

        #Variables on guardem les dates del dibuix
        vecpress = self.setcordpress
        vecrelease = self.setcordrelease
        #linias dibuixades=vecsize/2
        vecsize = np.int(vecpress.size)
        #Aquí guardarem els resultats.
        transformvectorx = np.array([], dtype=int)
        transformvectory = np.array([], dtype=int)

        #Coloquem una guasiana al voltant del potencial que pintem. La sigma^2 farem que
        #sigui del mateix tamany que el pas
        s2vec = self.dx
        valorVec = 10000.

        #Bucle de conversió de les dades
        for i in range(0, vecsize, 2):
            #Establim noms de variables
            index = i
            x0 = vecpress[index]
            y0 = vecpress[index + 1]
            x1 = vecrelease[index]
            y1 = vecrelease[index + 1]

            Vecgaussia = self.potential_maker(x0, y0, x1, y1, valorVec, s2vec)
            #I el sumem...
            self.Vvec += Vecgaussia
            #Coloquem una petita gaussiana al voltant de cada punt de sigma*2=self.dx/2
            #self.Vvec=Vvec
        #Modifiquem els respectius ac,vc
        #self.Vvec=Vvec
        print(self.Vvec)
        self.avec, self.cvec = ck.ac(self.r, self.Vvec, self.Nx)

        print('Applied!')

    def gaussian_maker(self, x, y, x0, y0, x1, y1, value, s2, *largs):
        """Introduïm aquí la gaussiana per cada x e y... x0,y0,x1,y1, son els
        dos punts que uneixen la recta dibuixada. Utilitzarem les rectes perpen-
        diculars en aquestes a cada punt per dissenyar aquest potencial."""

        #Primer de tot, definim el pendent de la recta que uneix els dos punts
        if (x1 - x0) == 0.:
            x_c = x0
            y_c = y

        else:

            m = (y1 - y0) / (x1 - x0)

            if m == 0:
                y_c = y0
                x_c = x
            else:
                x_c = 0.5 * (x0 + x - (y0 - y) / m)
                y_c = m * (x_c - x0) + y0
        #definim condicio per si posar-hi gaussiana o no:
        if x0 - self.dx < x_c < x1 + self.dx:
            #Obteim el punt en y
            #Ara només hem de calcular quant val la gaussiana:
            Vvecgauss = value * (1. / (np.sqrt(s2 * 2. * np.pi))) * np.exp(
                -(0.5 / s2) * ((x - x_c)**2 + (y - y_c)**2))
        else:
            Vvecgauss = 0.
        return Vvecgauss

    def potential_maker(self, x0, y0, x1, y1, value, s2, *largs):
        Vvecgauss1 = np.array([[
            self.gaussian_maker(self.xa + i * self.dx, self.xa + j * self.dx,
                                x0, y0, x1, y1, value, s2)
            for i in range(self.Nx + 1)
        ] for j in range(self.Nx + 1)])

        return Vvecgauss1

    def clear(self, *largs):
        """Aquesta funció neteja el canvas i tot els canvis introduïts 
        tan al potencial com a les coordenades del potencial. """
        self.paint.canvas.clear()
        self.setcordpress = np.array([])
        self.setcordrelease = np.array([])
        if self.mode == 0:

            self.Vvec = self.Vvecestandar

        if self.mode == 1:
            self.Vvec = self.Vvecslit

    ############################## MODES####################################
    #Aquestes funcions s'activen quan clikem self o slit i s'encarreguen de que
    #resetejar tot el que hi ha en pantalla (si estan en un mode difent al seu
    #propi) i posar el mode escollit
    #1.standard(mode 0)
    #2.slit(mode slit)

    def standard(self, *largs):
        """Funció que retorna el mode estandard en tots els aspectes: de càlcul,
        en pantalla, etf..."""
        if self.mode == 0:
            pass
        else:

            self.Vvec = self.Vvecestandar
            self.psi0 = self.psiestandar
            #Llevem les líneas que hi pogui haver
            if self.mode == 1:
                self.lineslit1.remove()
                self.lineslit2.remove()

            #Això es un reset, pensar fer-ho amb el reset.
            #Canviem la pantalla i el mode:
            self.i = 0
            #Rseteja la imatge

            self.normavec = ck.norma(self.psi0, self.Nx)
            self.visu_im.remove()
            #Posar el nou
            self.visu_im = self.visu.imshow(self.normavec,
                                            origin={'lower'},
                                            extent=(-self.L, self.L, -self.L,
                                                    self.L))
            #I utilitzar-lo
            self.main_canvas.draw()
            #Canviem el temps tambe
            self.t_total = 0.
            self.box3.tempschange.text = 'temps=0.'
            self.px = 0
            self.py = 0
            self.box3.pxchange.text = 'px=0'
            self.box3.pychange.text = 'py=0'
            self.mode = 0

    def slit(self, *largs):
        """Quan activem aquest buto, canviem el paquet de referencia i el 
        potencial de referència i ho deixem en el mode slit. Aquest mode
        correspon amb el número 1."""
        self.mode = 1
        self.Vvec = self.Vvecslit
        self.psi0 = self.psislit
        """Pintem tot lo dit i afegim una líniea que es correspón amb el potencial,
        fix en aquest mode."""

        #Rseteja la imatge

        self.normavec = ck.norma(self.psi0, self.Nx)
        self.visu_im.remove()
        #Posar el nou
        self.visu_im = self.visu.imshow(self.normavec,
                                        origin={'upper'},
                                        extent=(-self.L, self.L, -self.L,
                                                self.L))

        self.lineslit1 = self.visu.axvline(x=-self.L + self.xposslit * self.dx,
                                           ymin=0,
                                           ymax=0.475,
                                           color='white')

        self.lineslit2 = self.visu.axvline(
            x=-self.L + self.xposslit * self.dx,
            ymin=0.525,
            ymax=1,
            color='white',
        )
        #I utilitzar-lo
        self.main_canvas.draw()

    ################################### COMPUTE PARAMETES#####################
    #Aquestes funcions efectuan càlculs de diferents parametres. De moment,
    # només de l'energia i la norma
    #1.compute_parameters

    def compute_parameters(self, *largs):
        """Aquesta funció s'encarrega de calcular la norma i la energia del
        paquet en un cert instant t i despres l'ensenya a pantalla."""

        #Calculem moments i energia inicials i els posem al lloc corresponent
        self.normavec = ck.norma(self.psi0, self.Nx)

        self.norma0 = ck.trapezis(self.xa, self.xb, self.dx,
                                  np.copy(self.normavec))
        self.energy0 = ck.Ham(self.xa, self.xb, self.dx, np.copy(self.psi0))
        self.box3.normachange.text = 'Norma={0:.3f}'.format(self.norma0)
        self.box3.energychange.text = 'Energia={0:.3f}'.format(self.energy0)

    ##################################### JOC ##########################
    #Funcions relacionades amb el propi joc
    #1._keyboard_closed
    #2._on_keyboard_down
    #3.on_position
    #4.on_game

    def _keyboard_closed(self):
        """No se ben bé que fa però es necessària"""
        self._keyboard.unbind(on_key_down=self._on_keyboard_down)

        self._keyboard = None

    def _on_keyboard_down(self, keyboard, keycode, text, modifiers, *largs):
        """Aquesta funció s'ocupa de conectar el moviment del quadrat amb 
        el teclat. És a dir, conecta l'esdeveniment de teclejar  amb el de
        fer que el quadrat avanci un pas. A l'hora, també imposa els limits on
        el quadrat es pot moure.
        """
        #Definim els limits superior e inferior
        xliminf = np.int(self.cantonsnew[0, 0])
        xlimsup = np.int(self.cantonsnew[2, 0])
        yliminf = np.int(self.cantonsnew[0, 1])
        ylimsup = np.int(self.cantonsnew[1, 1])

        #defim el pas
        pas = 10
        #definim a quina distància s'ha de parar el rectangle.
        w = self.quadrat.width
        h = self.quadrat.height
        #Hem de pensar que la posició es defineix a la  cantonada inferior esquerre
        #del rectangle
        dist = 5

        #Conexions events amb moviment quadrat
        if keycode[1] == 'w':
            if self.quadrat.y + dist + h > ylimsup:
                pass
            else:
                self.quadrat.y += pas
                self.position = self.quadrat.pos
            return True

        if keycode[1] == 's':
            if self.quadrat.y - dist < yliminf:
                pass
            else:
                self.quadrat.y -= pas
                self.position = self.quadrat.pos
            #self.position=self.quadrat.position
            #print(self.quadrat.position)
            return True

        if keycode[1] == 'd':
            if self.quadrat.x + dist + w > xlimsup:
                pass
            else:
                self.quadrat.x += pas
                self.position = self.quadrat.pos
            return True

        elif keycode[1] == 'a':
            if self.quadrat.x - dist < xliminf:
                pass
            else:
                self.quadrat.x -= pas
                self.position = self.quadrat.pos
            return True

    def on_position(self, quadrat, pos):
        """Cada cop que el quadrat canvia de posició, això es notifica aquí.
        Utilitzarem aquesta funció (que està anclada a una propietat) per fer
        el canvi de coordenades pixels matplotlib-data matplotlib.
        Tot seguït, sabent on es troba el paquet, podem saber a sobre de quin 
        valor de densitat del paquet es troba i definir que passa quan es troba
        en segons quines situacions..."""

        #Utilitzem la transformació inversa que ens porta de pixels matplotlib
        # a dades matplotlib.
        inv_data = self.visu.transData.inverted()

        #Posició del centre del quadrat
        pos_data = inv_data.transform((pos[0] + self.quadrat.width / 2,
                                       pos[1] + self.quadrat.height / 2))

        #Un cop tenim la posició del centre del quadrat en coordenades data, les
        #pasem a coord del discretitzat:
        self.pos_discret = np.array([(pos_data[0] + self.L) / self.dx,
                                     (pos_data[1] + self.L) / self.dx],
                                    dtype=int)

        #Busquem el valor màxim de normavec cada cop que es mou el paquet
        #definim un llindar a partir del qual el quadrat detecta el paquet
        self.maxvalue = np.amax(self.normavec)
        self.llindar = self.maxvalue / 20.

        if self.normavec[self.pos_discret[0],
                         self.pos_discret[1]] > self.llindar:
            print('Touched')

    def gameon(self, *largs):
        """Aquesta funció es l'encarregada de posar el joc en marxa. Col·loca
        el quadradet a algún lloc on es pogui veure (una mica cutre però 
        ja ho canviaras). Uneix la funció teclat amb el moviment del quadrat,
        i varia el mode del joc."""

        if self.play_game == False:

            self.play_game = True
            self.quadrat.x = np.int(
                (-self.cantonsnew[0, 0] + self.cantonsnew[2, 0]) / 5. +
                self.cantonsnew[0, 0])
            self.quadrat.y = np.int(
                3 * (-self.cantonsnew[0, 1] + self.cantonsnew[1, 1]) / 4. +
                self.cantonsnew[0, 1])
            self._keyboard.bind(on_key_down=self._on_keyboard_down)

        else:
            self.play_game = False
            self.quadrat.x = 800
            self.quadrat.y = 600

            self._keyboard.unbind(on_key_down=self._on_keyboard_down)