Ejemplo n.º 1
0
    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
class SimulacionScreenLayout(BoxLayout):
    def __init__(self, **kwargs):
        super(SimulacionScreenLayout, self).__init__(**kwargs)
        self.padding = [10, 10, 10, 10]
        self.orientation = 'vertical'
        self.faselabel = WidgetCreator.newlabel("Nombre de Fase", size_hint=(1.0, None))
        self.add_widget(self.faselabel)
        chat = BoxLayout(orientation="horizontal", size_hint=(1, 1), spacing=10)
        chat.add_widget(WidgetCreator.newimage('assets/BotFace.jpg'))
        self.chatbox = ChatBox(size_hint=(1, 1))
        chat.add_widget(self.chatbox)
        self.add_widget(chat)
        self.camara = Image(size_hint=(1, 1), pos_hint={'top': 1})
        self.soundwave = FigureCanvasKivyAgg(AudioController().fig)
        self.userinputbox = UserInputBox(self.camara, self.soundwave, padding=[10, 10, 10, 10], spacing=10)
        self.add_widget(self.userinputbox)
        Clock.schedule_interval(self.update, 1.0 / 30.0)

    def update(self, dt):
        pose = camaracontroller.capturepose()
        self.userinputbox.poselabel.text = "Brazos: " + pose.name
        rostro = camaracontroller.capturegesture()
        self.userinputbox.rostrolabel.text = "Rostro: " + rostro.name
        if SelectorDeIconos.iconoderostro(rostro) is not None:
            self.userinputbox.rostroimage.source = SelectorDeIconos.iconoderostro(rostro)
        buf = camaracontroller.captureposeimage()
        self.soundwave.draw()
        if buf is not False:
            texture1 = Texture.create(size=(640, 480), colorfmt='bgr')
            texture1.blit_buffer(buf, colorfmt='bgr', bufferfmt='ubyte')
            self.camara.texture = texture1
Ejemplo n.º 3
0
class WiecejWykresow(Screen):
    wykresy = ObjectProperty()

    def wykres(self):
        filename = "nowyplik.gpx"
        self.fig = metody.wykres(filename)
        self.cnv = FigureCanvasKivyAgg(self.fig)
        self.wykresy.add_widget(self.cnv)
        self.cnv.draw()
Ejemplo n.º 4
0
class GraphWidget(BoxLayout):
    game_widget = None
    to_display = []
    graph_canvas = None
    fig = None
    ax = None

    paused = False

    nb_pointsdisplay = 1000
    refresh_rate = 10

    def __init__(self, **kwargs):
        super(GraphWidget, self).__init__(**kwargs)
        Clock.schedule_interval(self.update, 1.0 / self.refresh_rate)

        self.fig = plt.figure()
        self.ax = self.fig.add_subplot(111)
        self.line1, = self.ax.plot([])
        self.ax.set_ylabel("Score Mean")
        self.graph_canvas = FigureCanvasKivyAgg(figure=self.fig)

        self.add_widget(self.graph_canvas)

    def update(self, dt):
        if self.paused:
            return False
        if self.game_widget is None or len(self.game_widget.scores) == 0:
            return

        nb_scores = min(len(self.game_widget.scores), self.nb_pointsdisplay)
        x_data = range(0, nb_scores)
        start = len(self.game_widget.scores) - nb_scores
        y_data = self.game_widget.scores[start:]
        self.line1.set_ydata(y_data)
        min_val, max_val = np.min(self.game_widget.scores), np.max(
            self.game_widget.scores)
        val_range = max_val - min_val
        margin = 5 * val_range / 100
        self.ax.set_ylim(min_val - margin, max_val + margin)

        self.line1.set_xdata(x_data)
        self.ax.set_xlim(0, nb_scores)

        self.graph_canvas.draw()
        # self.graph_canvas.flush_events()

    def pause_resume(self):
        self.paused = not self.paused
        if not self.paused:
            Clock.schedule_interval(self.update, 1.0 / self.refresh_rate)
Ejemplo n.º 5
0
class IntensityPopup(Popup):
    def __init__(self):
        super(Popup, self).__init__()

        global intensitat_llum, Nx_inty, Ny_inty, w_det_ys

        self.inty_fig = plt.figure()
        self.inty_canvas = FigureCanvasKivyAgg(self.inty_fig)
        self.box2.add_widget(self.inty_canvas, 1)
        self.visu = plt.axes()
        self.inty_plot = self.visu.plot(
            intensitat_llum[int(Nx_inty / 2), w_det_ys:Ny_inty - w_det_ys])

        self.inty_canvas.draw()
Ejemplo n.º 6
0
class AddLocationForm(BoxLayout):
    my_map = ObjectProperty()
    plot = ObjectProperty()
    stat = ObjectProperty()

    def __init__(self, **kwargs):
        super(AddLocationForm, self).__init__(**kwargs)
        self.my_map.map_source = "osm-fr"
        self.fig = plt.figure()

    def analizuj_plik(self):
        filename = 'krk1.gpx'
        f.wczytaj_dane(filename)
        lat, lon = f.wczytaj_dane(filename)
        self.draw_route(lat, lon)

    def statystyka(self):  #statystyki
        filename = 'krk1.gpx'
        f.wczytaj_dane(filename)
        el, dates, DH, suma_odl, odl, czas_ost, czas, v, staty = f.statystyki(
            filename)
        self.stat.text = "{}".format(staty)  #wyswietlanie w aplikacji

    def draw_route(self, lat, lon):  #rysowanie trasy
        data_lay = MarkerMapLayer()
        self.my_map.add_layer(data_lay)  # my_map jest obiektem klasy MapView
        for point in zip(lat, lon):
            self.draw_marker(*point, layer=data_lay)

    def draw_marker(self, lat, lon, layer=None, markerSource='dot.png'):
        if lat != None and lon != None:
            marker = MapMarker(lat=lat, lon=lon, source=markerSource)
            self.my_map.add_marker(marker, layer=layer)

    def rysuj_wykres(self):
        filename = 'krk1.gpx'
        f.wczytaj_dane(filename)
        el, dates, DH, suma_odl, odl, czas_ost, czas, v, staty = f.statystyki(
            filename)
        self.ax1 = self.fig.add_subplot(111)
        self.ax1.scatter(czas, odl)
        self.ax1.set_xlabel('czas')
        self.ax1.set_ylabel('odl')
        self.ax1.set_title('Odleglosc do czasu')
        self.cnv = FigureCanvasKivyAgg(self.fig)
        self.plot.add_widget(self.cnv)
        self.cnv.draw()
Ejemplo n.º 7
0
    def showGraphs(self):
        if self.last_graphs is not None:
            self.ids.general_graphs.clear_widgets()
            self.ids.pareto_graph.clear_widgets()

            fitness_graph = FigureCanvasKivyAgg(self.last_graphs[0])
            individual_graph = FigureCanvasKivyAgg(self.last_graphs[1])
            pareto_graph = FigureCanvasKivyAgg(self.last_graphs[2])

            self.ids.general_graphs.add_widget(fitness_graph)
            fitness_graph.draw()
            self.ids.general_graphs.add_widget(individual_graph)
            individual_graph.draw()
            self.ids.pareto_graph.add_widget(pareto_graph)
            pareto_graph.draw()
Ejemplo n.º 8
0
class Classical(BoxLayout):
    time_label = StringProperty()
    but1 = StringProperty()
    but2 = StringProperty()
    but3 = StringProperty()
    language = StringProperty()

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

        #Language:
        self.language = "CA"
        self.time_label = "Temps"
        self.but1 = "Sobre el pic"
        self.but2 = "En el pic"
        self.but3 = "Sota el pic"
        self.cabut.color = (0,0.75,1,1)
        self.esbut.color = (1,1,1,1)
        self.enbut.color = (1,1,1,1)

        "Classical definitions"
        self.time_cla = 0.
        self.height_cla = 0.3
        self.sigma_cla =  1./(np.sqrt(2*np.pi)*self.height_cla)
        self.mu_cla = 0
        rob.m = 5

        self.R = 0.2

        self.k_cla = 0.5
        self.tmax_cla = 10

        self.xo_cla = 1.5
        self.yin0 = np.array([self.xo_cla,0.0])  #Check if this is needed.
        self.timeslide_cla.disabled = True  #It is not allowed to move the time bar.

        self.xarr_cla = xarr_cla = np.arange(-20, 20 + (20 - (-20))/float(1000)*0.1, (20 - (-20))/float(1000)) #Why not?
        #It initially used xarr_qua. But since the programs were separated, it uses this. It is only for plotting purposes.

        #Flux controllers.
        self.oldtop2_cla = self.height_cla
        self.oldk2_cla = self.k_cla

        #Clock (Classical):
        self.time_cla = 0.
        self.dtime0_cla = 0.01 #Default time step (used by RK4 and as default playing velocity).

        self.dtime_cla = 1.2*self.dtime0_cla #Defines the playing velocity = 1.

        self.oldtime1_cla = self.time_cla + 1
        self.oldrow = -1

        #Plots (Classical):
        self.canvas_cla = FigureCanvasKivyAgg(fig_cla)
        self.panel1.add_widget(self.canvas_cla)

        acl.axis('scaled')
        acl.set_xlabel("x (m)")
        acl.set_ylabel("y (m)")
        acl.axis([-2.5, 2.5, 0 , 3])

        self.ground_cla, = acl.plot(self.xarr_cla, rob.fground(self.mu_cla, self.sigma_cla, self.k_cla, self.xarr_cla), 'k--')
        self.filled_cla = acl.fill_between(self.xarr_cla, 0, rob.fground(self.mu_cla, self.sigma_cla, self.k_cla, self.xarr_cla), color = (0.5,0.5,0.5,0.5))
        self.ballcm, = acl.plot([], [], 'ro', ms=1)
        self.ballperim, = acl.plot([], [], 'r-', lw=1)
        self.filled_ball_cla = acl.fill_between([], []) #Empty one. Needs to be here in order to use self.name.remove() later.
        self.balldots, = acl.plot([], [], 'ro', ms=1)
        self.E_cla, = acl.plot([],[], 'g-.', lw=1, label = "E")
        acl.legend(loc=1)

        #First computations:
        self.demo1_cla_btn()
        Clock.schedule_interval(self.ballupdate, self.dtime0_cla)

#Classical functions:
    #Changing parameters:
    def plotground(self):
        #It is only activated if some value changes.
        a = self.oldtop2_cla != self.height_cla
        b = self.oldk2_cla != self.k_cla

        if a or b:
            self.oldtop2_cla = self.height_cla
            self.oldk2_cla = self.k_cla

            #Changes and plots the new ground.
            self.ground_cla.set_data(self.xarr_cla, rob.fground(self.mu_cla, self.sigma_cla, self.k_cla, self.xarr_cla))
            self.filled_cla.remove()
            self.filled_cla = acl.fill_between(self.xarr_cla, 0, rob.fground(self.mu_cla, self.sigma_cla, self.k_cla, self.xarr_cla),
            color = (0.5,0.5,0.5,0.5))



    #Plotting.
    def plotball_0(self):
        x = self.supermatrix_cla[0, 1]
        XXcm = rob.xcm(self.R, self.mu_cla, self.sigma_cla, self.k_cla, x)
        YYcm = rob.ycm(self.R, self.mu_cla, self.sigma_cla, self.k_cla, x)

        gamma = np.arange(0, 2*np.pi + 0.5*0.02/self.R, 0.02/self.R)
        half_gamma = np.arange(0, np.pi, 0.02/self.R)
        XXr = XXcm + self.R*np.cos(gamma)
        YYr = YYcm + self.R*np.sin(gamma)

        Xdots = []
        Ydots = []
        for i in [-1./2., 0., 1./2., 1.]:
            Xdots.append(XXcm + self.R*np.sin(self.angle[0] + i*np.pi)/2.)
            Ydots.append(YYcm + self.R*np.cos(self.angle[0] + i*np.pi)/2.)

        self.ballperim.set_data(XXr, YYr)
        self.filled_ball_cla.remove()
        self.filled_ball_cla = acl.fill_between(XXcm + self.R*np.cos(half_gamma), YYcm - self.R*np.sin(half_gamma),
        YYcm + self.R*np.sin(half_gamma), color = (1,0,0,0.2))
        self.ballcm.set_data(XXcm, YYcm)
        self.balldots.set_data(Xdots, Ydots)
        self.canvas_cla.draw()


    def plotball(self, t):
        if self.oldtime1_cla != t:
            if t >= self.supermatrix_cla[-1,0]:
                row = - 1

            else:
                row = int(t/self.dtime0_cla)

            if self.oldrow != row:
                x = self.supermatrix_cla[row, 1]
                XXcm = rob.xcm(self.R, self.mu_cla, self.sigma_cla, self.k_cla, x)
                YYcm = rob.ycm(self.R, self.mu_cla, self.sigma_cla, self.k_cla, x)

                gamma = np.arange(0, 2*np.pi + 0.5*0.02/self.R, 0.02/self.R)
                half_gamma = np.arange(0, np.pi, 0.02/self.R)
                XXr = XXcm + self.R*np.cos(gamma)
                YYr = YYcm + self.R*np.sin(gamma)

                Xdots = []
                Ydots = []
                for i in [-1./2., 0., 1./2., 1.]:
                    Xdots.append(XXcm + self.R*np.sin(self.angle[row] + i*np.pi)/2.)
                    Ydots.append(YYcm + self.R*np.cos(self.angle[row] + i*np.pi)/2.)

                self.ballperim.set_data(XXr, YYr)
                self.filled_ball_cla.remove()
                self.filled_ball_cla = acl.fill_between(XXcm + self.R*np.cos(half_gamma), YYcm - self.R*np.sin(half_gamma),
                YYcm + self.R*np.sin(half_gamma), color = (1,0,0,0.2))
                self.ballcm.set_data(XXcm, YYcm)
                self.balldots.set_data(Xdots, Ydots)
                self.canvas_cla.draw()

                self.oldrow = row
            self.oldtime1_cla = t

    def plotE_cla(self):
        #Plots the initial energy as a height (maximum height).
        x = np.arange(-2.6, 2.6, 0.1)
        y = self.Eheight + 0*x
        self.E_cla.set_data(x,y)
        self.canvas_cla.draw()

    #Playing.
    def ballupdate(self, dt):
        self.time_cla = self.timeslide_cla.value + self.dtime_cla

        #It starts again if the time reaches the top.
        if self.time_cla >= self.tmax_cla:
            self.time_cla = 0

        self.timeslide_cla.value = self.time_cla
        self.plotball(self.time_cla)

    def reset_cla(self):
        #Sets time to 0
        self.timeslide_cla.value = 0
        self.time_cla = 0

    def demo1_cla_btn(self):
        self.reset_cla()

        self.height_cla = 0.8
        self.sigma_cla =  1./(np.sqrt(2*np.pi)*self.height_cla)
        self.k_cla = 0.8
        self.plotground()

        #This version does not compute anything. It just reads the precomputed matrices.
        self.supermatrix_cla = np.load("Demo1_cla/super.npy")
        self.angle = np.load("Demo1_cla/ang.npy")

        #Plots the maximum height:
        self.Eheight = np.load("Demo1_cla/ene.npy")
        self.plotE_cla()

        self.demo1_button_cla.color = (0,0.75,1,1)
        self.demo2_button_cla.color = (1,1,1,1)
        self.demo3_button_cla.color = (1,1,1,1)

    def demo2_cla_btn(self):
        self.reset_cla()

        self.height_cla = 0.9
        self.sigma_cla =  1./(np.sqrt(2*np.pi)*self.height_cla)
        self.k_cla = 0.8
        self.plotground()

        #This version does not compute anything. It just reads the precomputed matrices.
        self.supermatrix_cla = np.load("Demo2_cla/super.npy")
        self.angle = np.load("Demo2_cla/ang.npy")

        #Plots the maximum height:
        self.Eheight = np.load("Demo2_cla/ene.npy")
        self.plotE_cla()

        self.demo2_button_cla.color = (0,0.75,1,1)
        self.demo1_button_cla.color = (1,1,1,1)
        self.demo3_button_cla.color = (1,1,1,1)

    def demo3_cla_btn(self):
        self.reset_cla()

        self.height_cla = 1
        self.sigma_cla =  1./(np.sqrt(2*np.pi)*self.height_cla)
        self.k_cla = 0.8
        self.plotground()

        #This version does not compute anything. It just reads the precomputed matrices.
        self.supermatrix_cla = np.load("Demo3_cla/super.npy")
        self.angle = np.load("Demo3_cla/ang.npy")

        #Plots the maximum height:
        self.Eheight = np.load("Demo3_cla/ene.npy")
        self.plotE_cla()

        self.demo3_button_cla.color = (0,0.75,1,1)
        self.demo2_button_cla.color = (1,1,1,1)
        self.demo1_button_cla.color = (1,1,1,1)

    def changecat(self):
        if self.language != "CA":
            self.language = "CA"
            self.time_label = "Temps"
            self.but1 = "Sobre el pic"
            self.but2 = "En el pic"
            self.but3 = "Sota el pic"
            self.cabut.color = (0,0.75,1,1)
            self.esbut.color = (1,1,1,1)
            self.enbut.color = (1,1,1,1)

    def changeesp(self):
        if self.language != "ES":
            self.language = "ES"
            self.time_label = "Tiempo"
            self.but1 = "Sobre el pico"
            self.but2 = "En el pico"
            self.but3 = "Bajo el pico"
            self.esbut.color = (0,0.75,1,1)
            self.cabut.color = (1,1,1,1)
            self.enbut.color = (1,1,1,1)

    def changeeng(self):
        if self.language != "EN":
            self.language = "EN"
            self.time_label = "Time"
            self.but1 = "Above the peak"
            self.but2 = "On the peak"
            self.but3 = "Under the peak"
            self.enbut.color = (0,0.75,1,1)
            self.esbut.color = (1,1,1,1)
            self.cabut.color = (1,1,1,1)
Ejemplo n.º 9
0
class TunnelPopup(Popup):
    
    amplada = NumericProperty()
    torn = StringProperty()
    
    
    def __init__(self,amplada):

        super(Popup, self).__init__()  
        
        self.bwidth = amplada
        self.color = 'red'
        self.gpseudo_init()
    

    def gpseudo_init(self): 
        
        self.hbar = 1.0
        self.massa = 1.0
        self.lx_max = 17.0
        self.lx_min = -17.0
        self.nx = 500
        self.dx = (self.lx_max - self.lx_min)/float(self.nx)
        self.xx = np.arange(self.lx_min,self.lx_max + self.dx,self.dx)
        self.dt = 0.01
        self.tmax = 1.5
        self.temps = 0.
        self.nt = (self.tmax/self.dt)+1
        self.r = 1j*self.dt/(2.0*(self.dx**2))
        
        self.p0 = -200.0/self.lx_max
        self.bheight_quadrat = 76.0
        self.bheight_gauss = 0.1
        self.potencial()
        self.control_pot = 'quadrat'
        self.max_pot = 90.0
        self.min_pot = 0.0
        self.phi0()
        self.phi02 = abs(self.phi0)**2
        
        self.colpot = 'yellow'
        self.cole = 'green'
        self.colphi = 'red'
  
        self.main_fig = plt.figure()
        self.main_fig.patch.set_facecolor('white')
        self.main_canvas = FigureCanvasKivyAgg(self.main_fig)
        self.main_canvas.bind(on_touch_up = self.control_teclat)
        self.box1.add_widget(self.main_canvas)
            
        self.pot_graf = plt.subplot()
        self.pot_graf.set_facecolor('black')
        self.pot_graf.axis([self.lx_min, self.lx_max, self.min_pot, self.max_pot])
        self.pot_data, = self.pot_graf.fill(self.xx, self.pot,color = self.colpot)
        self.e_data, = self.pot_graf.plot(self.xx,self.E_vect,color = self.color)
        
        self.ona = self.pot_graf.twinx()
        self.visu_ona, = self.ona.fill(self.xx,self.phi02, color = self.color)
        self.ona.axis([self.lx_min,self.lx_max,0.0,1.0])
        
        #"Pantalla" on es veurè el coeficient de transmissió analític
        self.pant1 = plt.figure()
        self.pant1.patch.set_facecolor('white')
        self.pant1_canvas = FigureCanvasKivyAgg(self.pant1)
        self.box2.add_widget(self.pant1_canvas)
        
        self.T_txt = self.pant1.text(0.1, 0.5,'%.8f' % (self.T))
        
        #"Pantalla" on es veurà la probabilotat de l'ona d'estar a l'esquerra de la barrera
        self.pant2 = plt.figure()
        self.pant2.patch.set_facecolor('white')
        self.pant2_canvas = FigureCanvasKivyAgg(self.pant2)
        self.box3.add_widget(self.pant2_canvas)
        
        self.prob_left_txt = self.pant2.text(0.1,0.5,'0.00000000')
        
        self.pant3 = plt.figure()
        self.pant3.patch.set_facecolor('white')
        self.pant3_canvas = FigureCanvasKivyAgg(self.pant3)
        self.box4.add_widget(self.pant3_canvas)
        
        self.norma_txt = self.pant3.text(0.1,0.5,'1.00000000')
        
                                    
        self.main_fig.tight_layout() 
        self.main_canvas.draw()
        
      
        
        
    def potencial(self):
        
        #self.pot = 42.55*(np.exp(-(self.xx/self.bwidth)**2))/np.sqrt(self.bheight_gauss*np.pi)
        self.pot = np.zeros(len(self.xx))
        for i in range(0,len(self.xx)):
            if -self.bwidth/2.0 < self.xx[i] < self.bwidth/2.0:
                self.pot[i] = self.bheight_quadrat
                
    def canvi_potencial_gauss(self):
        
        self.pot = 42.55*(np.exp(-(self.xx/self.bwidth)**2))/np.sqrt(self.bheight_gauss*np.pi)
        self.control_pot  = 'gauss'
        
        self.pot_data.remove()
        self.pot_data, = self.pot_graf.fill(self.xx, self.pot,color=self.colpot)
        
        self.T_analitic()
        self.T_txt.remove()
        self.T_txt = self.pant1.text(0.1, 0.5,str(self.T))
        
        self.main_canvas.draw()
        self.pant1_canvas.draw()
        
    def canvi_potencial_quadrat(self):
        
        self.pot = np.zeros(len(self.xx))
        for i in range(0,len(self.xx)):
            if -self.bwidth/2.0 < self.xx[i] < self.bwidth/2.0:
                self.pot[i] = self.bheight_quadrat
            
        self.pot_data.remove()
        self.pot_data, = self.pot_graf.fill(self.xx, self.pot,color=self.colpot)
        
        self.T_analitic()
        self.T_txt.remove()
        self.T_txt = self.pant1.text(0.1, 0.5,str(self.T))
        
        self.main_canvas.draw()
        self.pant1_canvas.draw()
        
            

    def phi0(self):
        
        self.phi0 = 1j*np.zeros(len(self.xx))
        self.phi0 = (1.0/(2.0*np.pi)**(1.0/4.0))*np.exp((-(self.xx - 7.0)**2)/4.0)*np.exp(1j*self.xx*self.p0)
        self.energia()
        self.T_analitic()
    
    def energia(self):
        
        self.matriu_H = np.zeros((self.nx+1,self.nx+1))
        k = 1.0/(self.dx**2)
        for i in range(0,self.nx+1):
            self.matriu_H[i,i] = self.pot[i] + k
            if i != self.nx:
                self.matriu_H[i,i+1] = -(k/2.0)
                self.matriu_H[i+1,i] = -(k/2.0)
    
        
        self.phihphi = (np.conjugate(self.phi0)*(np.dot(self.matriu_H,self.phi0)))
        
        self.E = self.simpson2(self.dx,self.phihphi)
        
        self.E_vect = np.zeros((self.nx+1))
        
        for i in range(0,self.nx+1):
            self.E_vect[i] = self.E
        

    def simpson2(self,h,vect):
        
        #add the extrems
        add=(vect[0]+vect[len(vect)-1])

        #add each parity its factor
        for i in np.arange(2,len(vect)-1,2):
            add+=2*vect[i]

        for i in np.arange(1,len(vect)-1,2):
            add+=4*vect[i]

        #add the global factor
        add*=(h/np.float(3))

        return add 
        
    def add_width(self):
        
        self.pot_data.remove()
        self.T_txt.remove()
        self.bwidth = self.bwidth + 0.05
        self.potencial()
        self.T_analitic()
        self.T_txt = self.pant1.text(0.1, 0.5,str(self.T))
        self.pot_data, = self.pot_graf.fill(self.xx, self.pot,color=self.colpot)
        
        self.pant1_canvas.draw()
        self.main_canvas.draw()

        
    def subtract_width(self):
        
        self.pot_data.remove()
        self.T_txt.remove()
        self.bwidth = self.bwidth - 0.05
        self.potencial()
        self.T_analitic()
        self.pot_data, = self.pot_graf.fill(self.xx, self.pot,color=self.colpot)
        self.T_txt = self.pant1.text(0.1, 0.5,'%.8f' % (self.T))
        
        self.pant1_canvas.draw()
        self.main_canvas.draw()
        
    def add_bheight(self):
        
        self.pot_data.remove()
        self.T_txt.remove()
        self.bheight_quadrat = self.bheight_quadrat + 0.5
        self.potencial()
        self.T_analitic()
        self.pot_data, = self.pot_graf.fill(self.xx, self.pot,color=self.colpot)
        self.T_txt = self.pant1.text(0.1, 0.5,'%.8f' % (self.T))
        
        self.pant1_canvas.draw()
        self.main_canvas.draw()
        
    def subtract_bheight(self):
        
        self.pot_data.remove()
        self.T_txt.remove()
        self.bheight_quadrat = self.bheight_quadrat - 0.5
        self.potencial()
        self.T_analitic()
        self.pot_data, = self.pot_graf.fill(self.xx, self.pot,color=self.colpot)
        self.T_txt = self.pant1.text(0.1, 0.5,'%.8f' % (self.T))
        
        self.pant1_canvas.draw()
        self.main_canvas.draw()

        
    def T_analitic(self):
        
        self.arrel = []
        
        for i in range(0,self.nx+1):
            if self.pot[i] > self.E:
                self.arrel = np.append(self.arrel,np.sqrt(2.0*(self.pot[i]-self.E)))
        
        
        integral = self.simpson2(self.dx,self.arrel)
        #integral = (self.bwidth*np.sqrt(76.0-self.E))
        
        self.T = np.abs((np.exp((-2.0)*integral)))
        
        
        
        
    def inici_evolucio(self):
        
        self.ev = Clock.schedule_interval(self.evolucio,self.dt)

        #Es crearan els vectors i matriu necessaris per la evolucio
        self.abc()
        self.matriuB()
        self.phii = 1j*np.zeros(self.nx-1)
        for i in range(1,self.nx-1):
            self.phii[i] = self.phi0[i]
        self.phi = 1j*np.zeros(self.nx+1)
        self.phi2 = np.zeros(self.nx + 1)
        
        self.t = 0
        
        
    def abc(self):
        
        self.b = 1j*np.zeros(self.nx-1)
        self.a = 1j*np.zeros(self.nx-1)
        self.c = 1j*np.zeros(self.nx-1)
        
        for i in range(0,self.nx-1):
            self.b[i] = 2.0*(1.0 + self.r) + 1.0j*self.pot[i]*self.dt
            if i != 0:
                self.a[i] = -self.r
            if i != self.nx-2:
                self.c[i] = -self.r
        
        
    def stop_evolucio(self):
        
        self.ev.cancel()
        GlobalShared.prob = self.probleft
        print (GlobalShared.prob)
    
    def matriuB(self):
        
        self.matriu_B = 1j*np.zeros((self.nx -1,self.nx-1))
        for i in range(0,self.nx-1):
            self.matriu_B[i,i] = 2.0*(1.0 -self.r) - 1.0j*self.pot[i]*self.dt
            if i != (self.nx-2):
                self.matriu_B[i,i+1] = self.r
                self.matriu_B[i+1,i] = self.r
                
    def prob_left(self):
        
        n = int(self.nx/2)
        
        self.probleft = self.simpson2(self.dx,self.phi2[0:n])/self.simpson2(self.dx,self.phi2)
        
    def calc_norma(self):
        
        self.norma = self.simpson2(self.dx,self.phi2)
        
    def evolucio(self,dt):
        
        self.abc()
        self.matriuB()
        
        self.t += 100*self.dt
    
        self.d = np.dot(self.matriu_B,self.phii)
        
        # Apliquem condicions de contorn
        self.d[0] = self.d[0] + 2.0*self.r*self.phi0[0]
        self.d[self.nx-2] = self.d[self.nx-2] + 2.0*self.r*self.phi0[self.nx]
        
        
        # Cridem la subrutina tridiag que ens calculi phi pel temsp següent
        self.tridiag()
        
        self.phi[1:self.nx] = self.phii
        self.phi[0] = self.phi0[0]
        self.phi[self.nx] = self.phi0[self.nx]
        
        for i in range(0,self.nx+1):
            self.phi2[i] = (np.abs(self.phi[i]))**2
        
        #Ara per a cada temps ha de esborrar la figura anterior i 
        #dibuixar la nova
        
        self.visu_ona.remove()
        self.visu_ona, = self.ona.fill(self.xx,self.phi2,color = self.color)
        
        
        self.main_canvas.draw()
        
        if np.mod(self.t,5.0) == 0.0:
            #Cridem la funció que integra la funcio d'ona a l'esquerra
            self.prob_left()
        
            self.prob_left_txt.remove()
            self.prob_left_txt = self.pant2.text(0.1,0.5,'%.8f' % (self.probleft))
        
            #Cridem la funció que ens calcula la norma
            self.calc_norma()
        
            self.norma_txt.remove()
            self.norma_txt = self.pant3.text(0.1,0.5,'%.8f' % (self.norma))
        
            self.pant2_canvas.draw()
            self.pant3_canvas.draw()
            
        if self.t == 150:
            
            self.stop_evolucio()
        
        
    def tridiag(self):
    
        n = np.size(self.a)

        cp = np.zeros(n, dtype = np.complex)
        dp = np.zeros(n, dtype = np.complex)
        cp[0] = self.c[0]/self.b[0]
        dp[0] = self.d[0]/self.b[0]

        for i in range(1,n):
            m = (self.b[i]-self.a[i]*cp[i-1])
            cp[i] = self.c[i]/m
            dp[i] = (self.d[i] - self.a[i]*dp[i-1])/m

        self.phii[n-1] = dp[n-1]

        for j in range(1,n):
            i = (n-1)-j
            self.phii[i] = dp[i]-cp[i]*self.phii[i+1]

    
    def reset(self):
        
        self.stop_evolucio()
        self.visu_ona.remove()
        self.visu_ona, = self.ona.plot(self.xx,self.phi02, color = self.colphi)
        
        self.norma_txt.remove()
        self.prob_left_txt.remove()        
        self.prob_left_txt = self.pant2.text(0.1,0.5,'0.00000000')
        self.norma_txt = self.pant3.text(0.1,0.5,'1.00000000')
        
        self.pant2.canvas.draw()
        self.pant3.canvas.draw()
        self.main_canvas.draw()
    
    def _teclat_activat(self,keyboard, keycode, text, modifiers):
        if keycode[1] == 'spacebar':
            self.inici_evolucio()
            self._teclat.unbind(on_hey_down = self._teclat_activat)
        return
    
    def control_teclat(self, *args):
        
        
        self._teclat = Window.request_keyboard(self._teclat_tancat,self)
        self._teclat.bind(on_key_down=self._teclat_activat) 
                
      
    def _teclat_tancat(self):
        
        self._teclat.unbind(on_key_down=self._teclat_activat) 
Ejemplo n.º 10
0
class Quantum(BoxLayout):
    time_label = StringProperty()
    but1 = StringProperty()
    but2 = StringProperty()
    but3 = StringProperty()
    language = StringProperty()

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

        #Language:
        self.language = "CA"
        self.time_label = "Temps"
        self.but1 = "Sobre el pic"
        self.but2 = "En el pic"
        self.but3 = "Sota el pic"
        self.energy_label = "Energia"
        self.prob_label = "Densitat de probabilitat"
        self.cabut.color = (0, 0.75, 1, 1)
        self.esbut.color = (1, 1, 1, 1)
        self.enbut.color = (1, 1, 1, 1)

        "Quantum definitions"
        self.a = -20.
        self.b = 20.
        self.N = 1000
        self.deltax = (self.b - self.a) / float(self.N)

        te.factor = 10  #Factor for the applied potential.
        self.height_qua = 15  #Default
        self.sigma_qua = 2 * te.factor / (np.sqrt(2 * np.pi) * self.height_qua)
        self.mu_qua = 0
        self.xarr_qua = np.arange(self.a, self.b + self.deltax * 0.1,
                                  self.deltax)
        self.m_qua = 1 / (2 * 3.80995)  #The value contains hbar^2.
        te.hbar = 4.136  #eV·fs (femtosecond)
        self.k_qua = 0.2  #Default
        self.xo = -2.3  #Default
        te.sigma0 = 0.4  #Default.
        self.oldtop2_qua = self.height_qua
        self.oldk2_qua = self.k_qua

        #Clock (Quantum):
        Clock.schedule_interval(self.psiupdate, 1 / 60)
        self.dtime0_qua = 1 / 30
        self.vel_qua = 1
        self.dtime_qua = self.vel_qua * self.dtime0_qua
        self.time_qua = 0.0
        self.tmax_qua = 10
        self.oldtime1_qua = self.time_qua + 1

        #Time
        self.timeslide_qua.disabled = True  #It is not allowed to move the time bar.

        #Plots (Quantum)
        self.canvas_qua = FigureCanvasKivyAgg(fig_qua)
        self.pot_qua, = aqu.plot(self.xarr_qua,
                                 te.pot(self.mu_qua, self.sigma_qua,
                                        self.k_qua, self.xarr_qua),
                                 'k--',
                                 label="V(x)")
        self.filled_pot_qua = aqu.fill_between(self.xarr_qua,
                                               te.pot(self.mu_qua,
                                                      self.sigma_qua,
                                                      self.k_qua,
                                                      self.xarr_qua),
                                               color=(0.5, 0.5, 0.5, 0.5))
        self.energy_qua, = aqu.plot([], [], '-.', color='g', label="<E>")
        aqu.plot([], [], 'r-',
                 label=r'$|\Psi(x)|^{2}$')  #Fake one, just for the legend.
        aqu.axis([-5, 5, 0, 2 * te.factor])
        aqu.set_xlabel("x (" + u"\u212B" + ")")
        aqu.set_ylabel(self.energy_label + " (eV)", color='k')
        aqu.tick_params('y', colors='k')
        aqu.legend(loc=1)

        #The wavefunction is plotted in a different scale.
        self.psi_qua, = aqu2.plot(self.xarr_qua,
                                  np.abs(te.psi(self.xo, self.xarr_qua))**2,
                                  'r-')
        self.filled_qua = aqu2.fill_between(self.xarr_qua,
                                            np.abs(
                                                te.psi(self.xo,
                                                       self.xarr_qua))**2,
                                            color=(1, 0, 0, 0.2))
        aqu2.axis([-5, 5, 0, 1])
        aqu2.set_ylabel(self.prob_label, color='k')
        aqu2.tick_params('y', colors='r')
        self.panel2.add_widget(self.canvas_qua)

        #First computations:
        self.demo1_qua_btn()


#Quantum functions:
#Plotting:

    def plotpot(self):
        #It is only activated if some value changes.
        a = self.oldtop2_qua != self.height_qua
        b = self.oldk2_qua != self.k_qua

        if a or b:
            self.pot_qua.set_data(
                self.xarr_qua,
                te.pot(self.mu_qua, self.sigma_qua, self.k_qua, self.xarr_qua))
            self.filled_pot_qua.remove()
            self.filled_pot_qua = aqu.fill_between(
                self.xarr_qua,
                te.pot(self.mu_qua, self.sigma_qua, self.k_qua, self.xarr_qua),
                color=(0.5, 0.5, 0.5, 0.5))

            self.oldtop2_qua = self.height_qua
            self.oldk2_qua = self.k_qua

    def plotpot1(self):
        #It is only activated if some value changes.
        a = self.oldtop2_qua != self.height_qua
        b = self.oldk2_qua != self.k_qua

        if a or b:
            self.pot_qua.set_data(
                self.xarr_qua,
                te.pot1(self.mu_qua, self.sigma_qua, self.k_qua,
                        self.xarr_qua))
            self.filled_pot_qua.remove()
            self.filled_pot_qua = aqu.fill_between(
                self.xarr_qua,
                te.pot1(self.mu_qua, self.sigma_qua, self.k_qua,
                        self.xarr_qua),
                color=(0.5, 0.5, 0.5, 0.5))

            self.oldtop2_qua = self.height_qua
            self.oldk2_qua = self.k_qua

    def plotpsi(self, t):
        if self.oldtime1_qua != t:
            psit = np.abs(te.psiev(self.evalsbasis, self.coef_x_efuns, t))**2
            self.psi_qua.set_data(self.xarr_qua, psit)
            self.filled_qua.remove()
            self.filled_qua = aqu2.fill_between(self.xarr_qua,
                                                psit,
                                                color=(1, 0, 0, 0.2))
            self.canvas_qua.draw()
            self.oldtime1_qua = t

    #Playing:
    def psiupdate(self, dt):
        self.time_qua = self.timeslide_qua.value + self.dtime_qua
        if self.time_qua >= self.tmax_qua:
            self.time_qua = 0
        self.timeslide_qua.value = self.time_qua
        self.plotpsi(self.time_qua)

    def reset(self):
        #Sets time to 0
        self.timeslide_qua.value = 0
        self.time_qua = 0
        self.tmax_qua = 10

    def demo1_qua_btn(self):
        self.reset()
        #This version does not compute anything. It just reads the precomputed matrices.
        self.coef_x_efuns = np.load("Demo1_qua/vecs.npy")
        self.evalsbasis = np.load("Demo1_qua/vals.npy")

        #Potential:
        self.height_qua = 40
        self.sigma_qua = 2 * te.factor / (np.sqrt(2 * np.pi) * self.height_qua)
        self.k_cla = 0.2
        self.plotpot1()

        #Plots the enrgy:
        self.energy = np.load("Demo1_qua/ene.npy")
        self.energy_qua.set_data(self.xarr_qua,
                                 0 * self.xarr_qua + self.energy)
        self.energy_qua.set_color('g')
        self.energy_qua.set_label("<E>")
        aqu.legend(loc=1)
        self.canvas_qua.draw()

        self.demo1_button_qua.color = (0, 0.75, 1, 1)
        self.demo2_button_qua.color = (1, 1, 1, 1)
        self.demo3_button_qua.color = (1, 1, 1, 1)

    def demo2_qua_btn(self):
        self.reset()
        #This version does not compute anything. It just reads the precomputed matrices.
        self.coef_x_efuns = np.load("Demo2_qua/vecs.npy")
        self.evalsbasis = np.load("Demo2_qua/vals.npy")

        #Potential:
        self.height_qua = 10
        self.sigma_qua = 2 * te.factor / (np.sqrt(2 * np.pi) * self.height_qua)
        self.k_cla = 0.2
        self.plotpot()

        #Plots the enrgy:
        self.energy = np.load("Demo2_qua/ene.npy")
        self.energy_qua.set_data(self.xarr_qua,
                                 0 * self.xarr_qua + self.energy)
        self.energy_qua.set_color('g')
        self.energy_qua.set_label("<E>")
        aqu.legend(loc=1)
        self.canvas_qua.draw()

        self.demo2_button_qua.color = (0, 0.75, 1, 1)
        self.demo1_button_qua.color = (1, 1, 1, 1)
        self.demo3_button_qua.color = (1, 1, 1, 1)

    def demo3_qua_btn(self):
        self.reset()
        #This version does not compute anything. It just reads the precomputed matrices.
        self.coef_x_efuns = np.load("Demo3_qua/vecs.npy")
        self.evalsbasis = np.load("Demo3_qua/vals.npy")

        #Potential:
        self.height_qua = 13
        self.sigma_qua = 2 * te.factor / (np.sqrt(2 * np.pi) * self.height_qua)
        self.k_cla = 0.2
        self.plotpot()

        psit = np.abs(te.psiev(self.evalsbasis, self.coef_x_efuns, 0))**2
        self.psi_qua.set_data(self.xarr_qua, psit)
        self.filled_qua.remove()
        self.filled_qua = aqu2.fill_between(self.xarr_qua,
                                            psit,
                                            color=(1, 0, 0, 0.2))
        self.canvas_qua.draw()

        #Plots the enrgy:
        self.energy = np.load("Demo3_qua/ene.npy")
        self.energy_qua.set_data(self.xarr_qua,
                                 0 * self.xarr_qua + self.energy)
        self.energy_qua.set_color('g')
        self.energy_qua.set_label("<E>")
        aqu.legend(loc=1)
        self.canvas_qua.draw()

        self.demo3_button_qua.color = (0, 0.75, 1, 1)
        self.demo2_button_qua.color = (1, 1, 1, 1)
        self.demo1_button_qua.color = (1, 1, 1, 1)

    def changecat(self):
        if self.language != "CA":
            self.language = "CA"
            self.time_label = "Temps"
            self.but1 = "Sobre el pic"
            self.but2 = "En el pic"
            self.but3 = "Sota el pic"
            self.energy_label = "Energia"
            self.prob_label = "Densitat de probabilitat"
            aqu.set_ylabel(self.energy_label + " (eV)", color='k')
            aqu2.set_ylabel(self.prob_label, color='k')
            self.cabut.color = (0, 0.75, 1, 1)
            self.esbut.color = (1, 1, 1, 1)
            self.enbut.color = (1, 1, 1, 1)

    def changeesp(self):
        if self.language != "ES":
            self.language = "ES"
            self.time_label = "Tiempo"
            self.but1 = "Sobre el pico"
            self.but2 = "En el pico"
            self.but3 = "Bajo el pico"
            self.energy_label = "Energía"
            self.prob_label = "Densidad de probabilidad"
            aqu.set_ylabel(self.energy_label + " (eV)", color='k')
            aqu2.set_ylabel(self.prob_label, color='k')
            self.esbut.color = (0, 0.75, 1, 1)
            self.cabut.color = (1, 1, 1, 1)
            self.enbut.color = (1, 1, 1, 1)

    def changeeng(self):
        if self.language != "EN":
            self.language = "EN"
            self.time_label = "Time"
            self.but1 = "Above the peak"
            self.but2 = "On the peak"
            self.but3 = "Under the peak"
            self.energy_label = "Energy"
            self.prob_label = "Probability density"
            aqu.set_ylabel(self.energy_label + " (eV)", color='k')
            aqu2.set_ylabel(self.prob_label, color='k')
            self.enbut.color = (0, 0.75, 1, 1)
            self.esbut.color = (1, 1, 1, 1)
            self.cabut.color = (1, 1, 1, 1)
Ejemplo n.º 11
0
class TrackForm(BoxLayout):
    destination = ObjectProperty()
    my_map = ObjectProperty()
    txt1 = ObjectProperty()
    txt2 = ObjectProperty()
    txt3 = ObjectProperty()
    txt4 = ObjectProperty()
    txt5 = ObjectProperty()
    txt6 = ObjectProperty()
    txt7 = ObjectProperty()
    txt8 = ObjectProperty()
    txt9 = ObjectProperty()
    plots = ObjectProperty()
    file = None
    data_lay = None

    def __init__(self, **kwargs):
        super(TrackForm, self).__init__(**kwargs)
        self.my_map.map_source = "thunderforest-outdoors"
        self.fig = plt.figure()
        self.cnv = FigureCanvasKivyAgg(self.fig)
        self.plots.add_widget(self.cnv)

    def rysuj_wykres(self):
        self.ax1 = self.fig.add_subplot(121)  #dodajemy tylko 1 wykres
        self.ax2 = self.fig.add_subplot(122)  #dodajemy tylko 1 wykres
        lon, lat, el, dates = g.czytanie(self.file)
        distance, Vsr, dH, dHplus, dHminus, Hmax, Hmin, h, m, s, alt_dif, d, v, k, j, l, n, S = g.parametry(
            lon, lat, el, dates)

        if alt_dif != [0]:
            self.ax1.scatter(d[l],
                             alt_dif[l],
                             label='the harderst part',
                             color='red')
            self.ax1.scatter(d[n],
                             alt_dif[n],
                             label='the easiest part',
                             color='black')
            self.ax1.plot(d[::20], alt_dif[::20])

            self.ax1.set_ylabel("dH[dist] [m]")

        if v != [0]:
            self.ax2.plot(d, v)
            self.ax2.scatter(d[k], v[k], label='the slowest part', color='red')
            self.ax2.scatter(d[j],
                             v[j],
                             label='the fastest part',
                             color='black')

            self.ax2.set_ylabel("v[dis]   [m/s]")

        self.ax1.legend()
        self.ax2.legend()
        self.cnv.draw()

    def open_file(self):
        self.txt1.text = ''
        self.txt2.text = ''
        self.txt3.text = ''
        self.txt4.text = ''
        self.txt5.text = ''
        self.txt6.text = ''
        self.txt7.text = ''
        self.txt8.text = ''
        self.txt9.text = ''
        self.fig.clear()
        self.cnv.draw()
        if self.data_lay is not None:
            self.my_map.remove_layer(self.data_lay)

        self.my_map.set_zoom_at(1, 0, 0, scale=None)
        self.my_map.center_on(0, 0)

        self.show_load()

    def analyse_file(self):
        if self.file == None:
            popup = Popup(title='Error',
                          content=Label(text='Lack of file'),
                          size_hint=(None, None),
                          size=(300, 100))
            popup.open()

        else:
            self.fig.clear()
            self.cnv.draw()
            self.rysuj_wykres()

            if self.file.endswith('.gpx'):
                lon, lat, el, dates = g.czytanie(self.file)
                self.draw_rout(lat, lon)

                distance, Vsr, dH, dHplus, dHminus, Hmax, Hmin, h, m, s, alt_dif, d, v, k, j, i, n, S = g.parametry(
                    lon, lat, el, dates)

                self.txt1.text = str(distance)
                self.txt1.text += '  [m]'

                if dHplus != 'brak':
                    self.txt2.text = str(dHplus)
                    self.txt2.text += '  [m]'

                    self.txt3.text = str(dHminus)
                    self.txt3.text += '  [m]'

                    self.txt4.text = str(dH)
                    self.txt4.text += '  [m]'

                    self.txt5.text = str(Hmax)
                    self.txt5.text += '  [m]'

                    self.txt6.text = str(Hmin)
                    self.txt6.text += '  [m]'

                    self.txt9.text = str(S)
                    self.txt9.text += '  [m]'

                else:
                    self.txt2.text = 'lack of date'
                    self.txt3.text = 'lack of date'
                    self.txt4.text = 'lack of date'
                    self.txt5.text = 'lack of date'
                    self.txt6.text = 'lack of date'
                    self.txt9.text = 'lack of date'

                if Vsr != 'brak':

                    self.txt7.text = str(Vsr)
                    self.txt7.text += '  [m/s]'

                    self.txt8.text = str(h)
                    self.txt8.text += '  [h] '
                    self.txt8.text += str(m)
                    self.txt8.text += '  [min] '
                    self.txt8.text += str(s)
                    self.txt8.text += '  [s] '

                else:

                    self.txt7.text = 'lack of date'
                    self.txt8.text = 'lack of date'

                self.my_map.set_zoom_at(8, 0, 0, scale=None)
                self.my_map.center_on(max(lat), max(lon))

            else:
                popup = Popup(title='Error',
                              content=Label(text='Incorrect file'),
                              size_hint=(None, None),
                              size=(300, 100))
                popup.open()

    def draw_rout(self, lat, lon):
        self.data_lay = MarkerMapLayer()
        self.my_map.add_layer(self.data_lay)
        lat = lat[::10]
        lon = lon[::10]

        for point in zip(lat, lon):
            self.draw_marker(*point, layer=self.data_lay)

    def draw_marker(self, lat, lon, layer=None):
        markerSource = 'dot.png'
        if lat != None and lon != None:
            marker = MapMarker(lat=lat, lon=lon, source=markerSource)
            self.my_map.add_marker(marker, layer=layer)

    def load_list(self, path, filename):
        self.file = filename[0]
        os.path.join(path, filename[0])
        self.dismiss_popup()

    def dismiss_popup(self):  # zamykanie okienka
        self._popup.dismiss()

    def show_load(self):
        content = LoadDialog(load=self.load_list, cancel=self.dismiss_popup
                             )  # powiazanie metod w oknie wczytywania plikow
        self._popup = Popup(title="Choose file",
                            content=content,
                            size_hint=(1, 1))
        self._popup.open()
class AddLocationForm(BoxLayout):

    my_map = ObjectProperty()
    lhmax = ObjectProperty()
    lhmin = ObjectProperty()
    lnachmax = ObjectProperty()
    lnachmin = ObjectProperty()
    ldh = ObjectProperty()
    plots = ObjectProperty()
    lvmax = ObjectProperty()
    lvmin = ObjectProperty()
    lvave = ObjectProperty()
    lczash = ObjectProperty()
    lczasm = ObjectProperty()
    lczass = ObjectProperty()
    ldyst = ObjectProperty()

    def __init__(self, **kwargs):
        super(AddLocationForm, self).__init__(**kwargs)
        self.fig = plt.figure()
        self.cnv = FigureCanvasKivyAgg(self.fig)
        self.plots.add_widget(self.cnv)

    def draw_marker(self):

        data_lay = MarkerMapLayer()
        self.my_map.add_layer(data_lay)
        for i in range(len(self.lati)):

            marker = MapMarker(lat=self.lati[i],
                               lon=self.loni[i],
                               source="dot.png")
            self.my_map.add_marker(marker, layer=data_lay)

        self.my_map.set_zoom_at(10, self.lati[1], self.loni[1], scale=None)
        self.my_map.center_on(self.lati[1], self.loni[1])

    def wczytaj(self):
        lat = []
        lon = []
        el = []
        dates = []
        gpx_file = open("2012.gpx", 'r')
        gpx = gpxpy.parse(gpx_file)
        gpx_file.close()
        for track in gpx.tracks:
            for seg in track.segments:
                for point in seg.points:
                    lon.append(point.longitude)
                    lat.append(point.latitude)

                    vfb = getattr(point, 'elevation')
                    if vfb == None:
                        pass
                    else:
                        el.append(point.elevation)

                    hsv = getattr(point, 'time')
                    if hsv == None:
                        pass
                    else:
                        hsv = getattr(point, 'time')
                        hsv = str(hsv)
                        dates.append(hsv)

        lat = lat[0::6]
        lon = lon[0::6]
        el = el[0::6]
        dates = dates[0::6]
        self.lati = lat
        self.loni = lon
        dh = [0]

        dist = [0]

        for i in range(len(lat)):
            if i == 0:
                pass
            else:
                aa = i - 1
                bb = i

                d = vin(lat[aa], lon[aa], lat[bb], lon[bb])
                dhcz = el[bb] - el[aa]
                D = math.sqrt(d**2 + dhcz**2)
                dh.append(dhcz)
                dist.append(D)

        n = []

        for a in range(len(lat)):
            if i == 0:
                pass
            else:
                if dist[a] == 0:
                    nach = 0
                else:

                    nach = (dh[a] / dist[a])
                    n.append(nach)

        h = []
        minute = []
        sec = []
        tpart = []
        if len(dates) > 1:
            ki = []
            wi = []
            for e in dates:
                e = str(e)
                aq = e.split("+")
                del aq[-1]
                yy = aq[0]
                ki.append(yy)
            for f in ki:
                f = str(f)
                ass = f.split(" ")
                ssa = ass[1]
                wi.append(ssa)
            for g in wi:
                g = str(g)
                qq = g.split(":")
                go = qq[0]
                m = qq[1]
                s = qq[2]
                h.append(go)
                minute.append(m)
                sec.append(s)
            czasyyy = []
            if len(dates) > 1:

                for i in range(len(h)):
                    czasyyy.append(
                        float(h[i]) + float(minute[i]) / 60 +
                        float(sec[i]) / 3600)
                for i in range(len(h)):
                    if i == 0:
                        pass
                    else:
                        aaa = i - 1
                        bbb = i
                        dtime = czasyyy[bbb] - czasyyy[aaa]
                        tpart.append(dtime)
            vparty = []

            if len(tpart) > 1:

                del dist[0]
                predkosc = zip(dist, tpart)
                for i, j in predkosc:
                    vvv = i / j
                    vparty.append(vvv)
                vparty = [i / 1000 for i in vparty]  #przeliczanie na km/h
                Vmax = max(vparty)
                Vmin = min(vparty)
                abba = [i / 1000 for i in dist]  #przeliczanie na km
                Vave = sum(abba) / sum(tpart)
                self.lvmax.text = str("%.3f" % Vmax)
                self.lvmin.text = str("%.3f" % Vmin)
                self.lvave.text = str("%.3f" % Vave)
                #rozdzielanie godziny na oczekiwane wartosci
                timeee = math.floor(sum(tpart))
                minuty = math.floor((sum(tpart) - timeee) * 60)
                sekundy = math.floor(
                    ((sum(tpart) - timeee) * 60 - minuty) * 60)
                self.lczash.text = str(timeee)
                self.lczasm.text = str(minuty)
                self.lczass.text = str(sekundy)
                dist.insert(0, 0)
                czasyyy.insert(0, 0)
                vparty.insert(0, 0)

        hmax = max(el)
        hmin = min(el)

        #profil
        self.ax1 = self.fig.add_subplot(111)
        self.ax1.set_xlabel('Dystans [km]')
        self.ax1.set_ylabel('Wysokosc m.n.p.m')
        plt.title('Profil wysokosciowy')

        self.ax1.plot(dod(dist), el)
        self.cnv.draw()

        #nachylenia w procentach
        f = max(n) * 100
        ff = min(n) * 100
        self.draw_route(lat, lon)
        self.lhmax.text = str("%.2f" % hmax)
        self.lhmin.text = str("%.2f" % hmin)
        self.lnachmax.text = str("%.2f" % f)
        self.lnachmin.text = str("%.2f" % ff)
        self.ldyst.text = str("%.2f" % sum(dist))
        self.ldh.text = str("%.2f" % sum(dh))

    def draw_route(self, lat, lon):
        data_layer = MarkerMapLayer()

        for point in zip(lat, lon):

            self.mark_point(*point, layer=data_layer)

    def mark_point(self, lat, lon, layer=None):
        if lat != None and lon != None:
            self.my_map.add_marker

    def kas(self):
        self.lhmax.text = "wczytaj dane"
        self.lhmin.text = "wczytaj dane"
        self.lnachmax.text = "wczytaj dane"
        self.lnachmin.text = "wczytaj dane"
        self.ldh.text = "wczytaj dane"
        self.lvmax.text = "wczytaj dane"
        self.lvmin.text = "wczytaj dane"
        self.lvave.text = "wczytaj dane"
        self.ldyst.text = "wczytaj dane"
Ejemplo n.º 13
0
class AddLocationForm(BoxLayout):  #stworzenie klasy

    txt1 = ObjectProperty()
    txt2 = ObjectProperty()
    my_map = ObjectProperty()
    plot = ObjectProperty()

    def __init__(self,
                 **kwargs):  # inicjalizacja dla klasy niedziedziczacej po App
        super(AddLocationForm, self).__init__(**kwargs)
        self.fig = plt.figure()  # stworzenie pustego wykresu
        self.cnv = FigureCanvasKivyAgg(
            self.fig
        )  # utworzenie wykresu w aplikacji na podstawie pustego wykresu
        self.plot.add_widget(
            self.cnv)  # dodanie wykresu do aplikacji do widgeta plots

#----------------wykres - profil wysokosci-------------------------------------

    def rysuj_wykres1(self):
        filename = self.txt1.text  #wczytanie pliku

        lat, lon, lat1, lat2, lon1, lon2, el, dates, elstart, elstop, datesstop, datesstart, delta, sekundy, sumdates, lat1wyk, lon1wyk = biblio.wczytaj_plik(
            filename)  #import danych

        def haversine1(
            orig, dest
        ):  #funkcja licząca odlegosć poziomą między punktem początkowym trasy a kolejnymi punktami trasy
            lat1wyk, lon1wyk = orig
            lat2, lon2 = dest
            radius = 6371000  # m

            dlat1 = np.radians(lat2 - lat1wyk)

            dlon1 = np.radians(lon2 - lon1wyk)

            a1 = np.sin(dlat1/2) * np.sin(dlat1/2) + np.cos(np.radians(lat1wyk)) \
            * np.cos(np.radians(lat2)) * np.sin(dlon1/2) * np.sin(dlon1/2)
            c1 = 2 * np.arctan2(np.sqrt(a1), np.sqrt(1 - a1))
            d1 = radius * c1

            return d1

        dist_part1 = haversine1((lat1wyk, lon1wyk), (lat2, lon2))
        D = list(dist_part1)  #utworzenie listy z odległosciami
        D.insert(
            0, 0
        )  #wprowadzenie odleglosci równej 0 w pierwszym punkcie trasy (aby móc zaznaczyć na wykresie wysokosć dla punktu początkowego)

        if el is not None:  #rysowanie wykresu, jesli wysokosc istnieje
            self.ax1 = self.fig.add_subplot(111)
            self.ax1.plot(D, el)
            plt.xlabel('Odległość pozioma [m]')
            plt.ylabel('Wysokość [m]')
            plt.title('Profil wysokościowy')
            self.cnv.draw()
            plt.savefig("wykres_profil.png")  #zapis do pliku
        else:
            pass

#----------------wykres - predkosc od odleglosci-------------------------------

    def rysuj_wykres2(self):
        filename = self.txt1.text  #wczytanie pliku

        lat, lon, lat1, lat2, lon1, lon2, el, dates, elstart, elstop, datesstop, datesstart, delta, sekundy, sumdates, lat1wyk, lon1wyk = biblio.wczytaj_plik(
            filename)  #import danych

        def haversine1(
            orig, dest
        ):  #funkcja licząca odlegosć poziomą między punktem początkowym trasy a kolejnymi punktami trasy
            lat1wyk, lon1wyk = orig
            lat2, lon2 = dest
            radius = 6371000  # m

            dlat1 = np.radians(lat2 - lat1wyk)

            dlon1 = np.radians(lon2 - lon1wyk)

            a1 = np.sin(dlat1/2) * np.sin(dlat1/2) + np.cos(np.radians(lat1wyk)) \
            * np.cos(np.radians(lat2)) * np.sin(dlon1/2) * np.sin(dlon1/2)
            c1 = 2 * np.arctan2(np.sqrt(a1), np.sqrt(1 - a1))
            d1 = radius * c1

            return d1

        dist_part1 = haversine1((lat1wyk, lon1wyk), (lat2, lon2))
        D = list(dist_part1)
        D.insert(0, 0)

        #------------------predkosci---------------------------------------------------

        def haversine(
            origin, destination
        ):  #funkcja licząca odleglosci na pomiedzy punktami trasy
            lat1, lon1 = origin
            lat2, lon2 = destination
            radius = 6371000  # m

            dlat = np.radians(lat2 - lat1)
            dlon = np.radians(lon2 - lon1)

            a = np.sin(dlat/2) * np.sin(dlat/2) + np.cos(np.radians(lat1)) \
            * np.cos(np.radians(lat2)) * np.sin(dlon/2) * np.sin(dlon/2)
            c = 2 * np.arctan2(np.sqrt(a), np.sqrt(1 - a))
            d = radius * c

            return d

        dist_part = haversine((lat1, lon1), (lat2, lon2))  # m
        #obliczenie prędkosci na odcinkach
        if sekundy > 0:
            v = dist_part / sekundy  #m/s
            V = list(v)
            V.insert(0, 0)
            self.ax1 = self.fig.add_subplot(111)
            self.ax1.plot(D, V)
            plt.xlabel('Odległość pozioma [m]')
            plt.ylabel('Prędkość [m/s]')
            plt.title('Wykres zależności prędkości od odległości poziomej')
            self.cnv.draw()
            plt.savefig("wykres_v_od_s).png")  #zapis do pliku
        else:
            pass

    def czyszczenie(self):  #funkcja czyszcząca
        self.txt2.text = ''  #nazwę pliku
        self.txt1.text = ''  #statystyki
        self.ax1.remove()  #wykres
        self.my_map.remove_layer(self.data_lay)  #znacznik na mapie

#------------------analiza trasy-----------------------------------------------

    def analyse_file(self):
        filename = self.txt1.text  #wczytanie pliku
        lat, lon, lat1, lat2, lon1, lon2, el, dates, elstart, elstop, datesstop, datesstart, delta, sekundy, sumdates, lat1wyk, lon1wyk = biblio.wczytaj_plik(
            filename)

        #---------------------HAVERSINE------------------------------------------------

        def haversine(origin, destination):
            lat1, lon1 = origin
            lat2, lon2 = destination
            radius = 6371000  # m

            dlat = np.radians(lat2 - lat1)
            dlon = np.radians(lon2 - lon1)

            a = np.sin(dlat/2) * np.sin(dlat/2) + np.cos(np.radians(lat1)) \
            * np.cos(np.radians(lat2)) * np.sin(dlon/2) * np.sin(dlon/2)
            c = 2 * np.arctan2(np.sqrt(a), np.sqrt(1 - a))
            d = radius * c

            return d

#------------------rysowanie poczatku trasy------------------------------------

        self.data_lay = MarkerMapLayer()
        self.my_map.add_layer(self.data_lay)
        marker = MapMarker(lat=lat[0], lon=lon[0], source="dot.png")
        self.my_map.add_marker(marker, layer=self.data_lay)

        #-----------------------obliczenia---------------------------------------------

        dist_part = haversine((lat1, lon1), (lat2, lon2))  # m
        sumdist = sum(dist_part)  #długosć całkowita trasy - pozioma
        alt_part = (elstop - elstart)  #przwyższenia na odcinkach trasy

        def przewyzszenie_dodatnie(alt_part):  #całkowite przewyższenie w górę
            dodatnie = []
            for przewyzszenie in alt_part:
                if przewyzszenie >= 0:
                    dodatnie.append(przewyzszenie)
            return dodatnie

        def przewyzszenie_ujemne(alt_part):  #całkowite przewyższenie w dół
            ujemne = []
            for przewyzszenie in alt_part:
                if przewyzszenie < 0:
                    ujemne.append(przewyzszenie)
            return ujemne

        altsum = sum(alt_part)  #całkowite przewyższenie na trasie
        odl3D = np.sqrt((dist_part**2 + alt_part**2))  #odległosć skosna
        sum3D = sum(odl3D)  #całkowita odleglosc skosna trasy

        #------------------predkosci---------------------------------------------------
        if sekundy > 0:
            v = dist_part / sekundy  #m/s
            vavg = sum(v) / len(v)
            p7 = str(round(vavg, 3))
        else:
            v = 0
            vavg = 0
            p7 = str('Brak')


#-------------wyswietlanie statystyk-------------------------------------------

        p1 = str(round(sumdist, 3))
        p2 = str(round(sum3D, 3))
        p3 = str(round(altsum, 3))
        p4 = str(round(sum(np.array(przewyzszenie_dodatnie(alt_part))), 3))
        p5 = str(round(sum(np.array(przewyzszenie_ujemne(alt_part))), 3))
        p6 = str(sumdates)
        p8 = str(round(max(el), 3))
        p9 = str(round(min(el), 3))

        self.txt2.text = 'Statystyki:'
        self.txt2.text += '\nCałkowita odległość (długość) pozioma [m]    '
        self.txt2.text += p1
        self.txt2.text += '\nCałkowita odległość skośna [m]    '
        self.txt2.text += p2
        self.txt2.text += '\nCałkowite przewyższenie [m]    '
        self.txt2.text += p3
        self.txt2.text += '\nw tym: w górę / w dół    '
        self.txt2.text += p4
        self.txt2.text += '  /  '
        self.txt2.text += p5
        self.txt2.text += '\nCzas [h:m:s]    '
        self.txt2.text += p6
        self.txt2.text += '\nSrednia predkość [m/s]    '
        self.txt2.text += p7
        self.txt2.text += '\nMaksymalna wysokość [m]    '
        self.txt2.text += p8
        self.txt2.text += '\nMinimalna wysokość [m]    '
        self.txt2.text += p9
class KivyCamera(FloatLayout):
    circle_pos = ListProperty([0, 0])
    # circle_y = NumericProperty(0)
    circle_r = NumericProperty(0)
    rect_pos = ListProperty([0, 0])
    coords_left = ListProperty()
    coords_bottom = ListProperty()
    coords_right = ListProperty()
    coords_top = ListProperty()
    coords_center = ListProperty()
    widths = ListProperty()
    active_function = StringProperty()

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

        # self.start()

    def start(self):
        # self.videostream = capture
        self.videostream = ThreadedVideoStream(0)
        self.videostream.start()
        # args for bigger video size: , frame_width=1920, frame_height=1080
        print("starting video capture")

        self.detector = dlib.get_frontal_face_detector()
        self.predictor = dlib.shape_predictor(
            "shape_predictor_68_face_landmarks.dat")

        self.hog = cv2.HOGDescriptor()
        self.hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
        # self.pos_hint = {'center_x': 0.5, 'center_y': 0.5}
        frame = self.videostream.read()
        # print("frame size; {}".format(frame.shape))

        self.sec = time.time()
        self.last_sec = self.sec
        self.wait_sec = 5
        self.random_s = random.randint(1, 10)
        self.touint8 = True

        # self.cam_screens = [self.original, self.original, self.sobel_cam,
        #                     self.sobel_cam, self.angle_cam, self.angle_cam,
        #                     self.mag_cam, self.mag_cam, self.hog_cam,
        #                     self.hog_cam, self.detect_faces, self.detect_faces]
        self.cam_screens = [
            self.original, self.grey_cam, self.blur_cam, self.sobelx_cam,
            self.sobely_cam, self.angle_cam, self.mag_cam, self.hog_cam,
            self.detect_faces
        ]
        self.screen_iter = iter(self.cam_screens)
        self.display_func = self.original

        dpi = inch(1)
        self.h_inch = int(frame.shape[0] / dpi)
        self.w_inch = int(frame.shape[1] / dpi)

        plt.rcParams['savefig.pad_inches'] = 0
        plt.style.use(['dark_background'])
        self.fig = plt.figure()  # figsize=(self.h_inch, h_inch)

        # Then we set up our axes (the plot region, or the area in which we plot things).
        # Usually there is a thin border drawn around the axes, but we turn it off with `frameon=False`.
        self.ax = plt.axes([0, 0, 1, 1], frameon=False)
        # Then we disable our xaxis and yaxis completely. If we just say plt.axis('off'),
        # they are still used in the computation of the image padding.
        self.ax.get_xaxis().set_visible(False)
        self.ax.get_yaxis().set_visible(False)

        # Even though our axes (plot region) are set to cover the whole image with [0,0,1,1],
        # by default they leave padding between the plotted data and the frame. We use tigher=True
        # to make sure the data gets scaled to the full extents of the axes.
        plt.autoscale(tight=True)
        self.ax.imshow(frame, 'brg')

        self.picture = FigureCanvasKivyAgg(figure=self.fig,
                                           size_hint=(None, None))
        self.picture.size = (frame.shape[1], frame.shape[0])
        self.picture.center_x = Window.width / 2
        self.picture.center_y = Window.height / 2

        self.label = Label(text='Gesichtserkennung wird gestartet ... \n',
                           size_hint=(None, None))
        self.label.x = 100
        self.label.center_y = Window.height / 2

        self.layout = FloatLayout(size_hint=(None, None))
        self.layout.add_widget(self.label)
        self.layout.add_widget(self.picture)
        self.add_widget(self.layout)

    def morphology_transform(self, img, morph_operator=2, element=1, ksize=18):
        morph_op_dic = {
            0: cv2.MORPH_OPEN,
            1: cv2.MORPH_CLOSE,
            2: cv2.MORPH_GRADIENT,
            3: cv2.MORPH_TOPHAT,
            4: cv2.MORPH_BLACKHAT
        }

        if element == 0:
            morph_elem = cv2.MORPH_RECT
        elif element == 1:
            morph_elem = cv2.MORPH_CROSS
        elif element == 2:
            morph_elem = cv2.MORPH_ELLIPSE

        elem = cv2.getStructuringElement(morph_elem,
                                         (2 * ksize + 1, 2 * ksize + 1),
                                         (ksize, ksize))
        operation = morph_op_dic[morph_operator]
        dst = cv2.morphologyEx(img, operation, elem)

        return dst

    def convert2uint8(self, frame, absolute=True):
        if absolute:
            frame = np.absolute(frame)
        return np.uint8(frame)

    def convert2uint32(self, frame, absolute=True):
        return np.uint32(frame)

    def original(self, frame, gray, uint8=True):
        self.active_function = "orig"
        self.wait_sec = 5
        return frame

    def grey_cam(self, frame, gray):
        self.active_function = "preproc"
        return gray

    def blur_cam(self, frame, gray):
        self.active_function = "preproc"
        return cv2.medianBlur(gray, 11)

    def sobelx_cam(self, frame, gray, uint8=True):
        self.active_function = "edge"
        blur = cv2.medianBlur(gray, 11)
        sobelx = cv2.Sobel(blur, cv2.CV_64F, 1, 0, ksize=3)

        return sobelx

    def sobely_cam(self, frame, gray, uint8=True):
        self.active_function = "edge"
        blur = cv2.medianBlur(gray, 11)
        sobely = cv2.Sobel(blur, cv2.CV_64F, 0, 1, ksize=3)

        return sobely

    def angle_cam(self, frame, gray, uint8=True):
        self.active_function = "edge"
        blur = cv2.medianBlur(gray, 11)
        sobelx = cv2.Sobel(blur, cv2.CV_64F, 1, 0, ksize=3)
        sobely = cv2.Sobel(blur, cv2.CV_64F, 0, 1, ksize=3)
        angle = np.arctan2(sobely, sobelx) * (180 / np.pi)

        return angle

    def mag_cam(self, frame, gray, uint8=True):
        self.active_function = "edge"
        blur = cv2.medianBlur(gray, 11)
        sobelx = cv2.Sobel(blur, cv2.CV_64F, 1, 0, ksize=3)
        sobely = cv2.Sobel(blur, cv2.CV_64F, 0, 1, ksize=3)
        mag = np.sqrt(sobelx**2.0 + sobely**2.0)

        return mag

    def hog_cam(self, frame, gray, uint8=True):
        self.active_function = "hog"
        (H, hogImage) = feature.hog(gray,
                                    orientations=9,
                                    pixels_per_cell=(8, 8),
                                    cells_per_block=(8, 8),
                                    transform_sqrt=True,
                                    block_norm="L1",
                                    visualize=True)

        hogImage = exposure.rescale_intensity(hogImage, out_range=(0, 255))

        return hogImage

    def detect_faces(self, frame, gray, uint8=True):
        self.active_function = "Detected Faces"
        # face detection
        faces = self.detector(gray, 1)
        filtered_frame = self.morphology_transform(frame.copy())

        for (i, face) in enumerate(faces):
            # shape = self.predictor(gray, face)
            # shape = face_utils.shape_to_np(shape)
            (x, y, w, h) = face_utils.rect_to_bb(face)
            # for (x, y) in shape:
            #     cv2.circle(frame, (x, y), 1, (0, 255, 0), -1)
            self.circle_r = (w + w / 2) / 2
            self.rect_pos = [face.right() / 2, face.top() / 2]
            circle_x = (x + w / 2)
            circle_y = (y + h / 2)

            rr, cc = circle(circle_y, circle_x, self.circle_r, frame.shape)
            filtered_frame[rr, cc] = frame[rr, cc]
            # morphed_frame[rr, cc] = frame[rr, cc]
            self.coords_left.append(frame.shape[1] - face.right())
            self.coords_bottom.append(frame.shape[0] - face.bottom())
            self.widths.append(face.width())

            c0 = self.coords_left[i] + (int(face.width() / 2))
            c1 = self.coords_bottom[i] + (int(face.width() / 2))
            self.circle_c.append([c0, c1])

        return filtered_frame

    def update(self, dt):
        frame = self.videostream.read()
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        self.label.texture_update()
        # add time value to return statements to change the time images are displayed
        self.sec = time.time()
        if (self.sec - self.last_sec) >= self.wait_sec:
            self.last_sec = self.sec
            # self.touint8 = not self.touint8
            try:
                self.display_func = next(self.screen_iter)
            except StopIteration:
                self.screen_iter = iter(self.cam_screens)
                self.label.text = 'Gesichtserkennung wird gestartet ... \n'
            if self.display_func == self.sobelx_cam:
                print('1')
                self.label.text += 'Suche Kanten ... \n'
                self.label.text += 'in x-Richtung ... \n'
            elif self.display_func == self.sobely_cam:
                self.label.text += 'erledigt. \n'
                self.label.text += 'in y-Richtung ... \n'
            elif self.display_func == self.angle_cam:
                self.label.text += 'erledigt. \n'
                self.label.text += 'Berechne Stärke ... \n'
            elif self.display_func == self.mag_cam:
                self.label.text += 'erledigt. \n'
                self.label.text += 'Berechne Richtung ... \n'
            elif self.display_func == self.hog_cam:
                self.label.text += 'erledigt. \n'
                self.label.text += 'Finde Gesichter ... \n'
            elif self.display_func == self.detect_faces:
                self.label.text += 'erledigt. \n\n'
            self.label.texture_update()

        # touint8 = True if self.wait_sec > 2 else False
        # self.remove_widget(self.picture)
        new_pic = self.display_func(frame, gray)
        new_pic = cv2.flip(new_pic, 1)
        col_fmt = None if (len(new_pic.shape) > 2) else 'gray'
        self.ax.imshow(new_pic, col_fmt)
        self.picture.draw()
        self.layout._trigger_layout()

        self.coords_left = []
        self.coords_bottom = []
        self.widths = []
        self.circle_c = []

    def stop(self):
        print("stopping video capture")
        self.videostream.stop()
Ejemplo n.º 15
0
class DoubleSlitScreen(BoxLayout):
    beep= SoundLoader.load('ping.wav')

    #Objects binded from .kv file
    p_rectangle = ObjectProperty()

    button_1slit = ObjectProperty()
    button_2slits = ObjectProperty()

    button_large = ObjectProperty()
    button_medium = ObjectProperty()
    button_small = ObjectProperty()

    label_speed = ObjectProperty()

    speed_slider = ObjectProperty()

    widget_plot = ObjectProperty()


    #Objects created here
    frame = NumericProperty(0) #current frame
    frames = NumericProperty(0) #total number of frames
    texture = ObjectProperty() #texture object (initialized at create_texture)
    zoom = NumericProperty(1) #this value autoadjusts when calling blit_P

    #Drawing parameters
    #size and position of he heatmap
    wh = 0
    hh = 0
    xh = 0
    yh = 0

    #Playback status and settings
    clock = None
    speed = NumericProperty(4)
    playing = True
    normalize_each_frame = True
    loop = True
    lasttime = time()

    #Simulation results
    Pt = None
    times = None
    maxP = 1

    slits = 2
    slit_size = "medium"

    current_filename = "lastsim"

    language = 0
    strings = {
    'slit': ['1 ranura', '1 ranura', '1 slit'],
    'slits': ['2 ranures', '2 ranuras', '2 slits'],
    'large': ['Grans', 'Grandes', 'Large'],
    'medium': ['Mitjanes', 'Medianas', 'Medium'],
    'small': ['Petites', 'Pequeñas', 'Small'],
    'speed': ['Velocitat', 'Velocidad', 'Speed']}

    measures_popup = ObjectProperty()

    def __init__(self, *args, **kwargs):
        super(DoubleSlitScreen, self).__init__(*args, **kwargs)

        self.canvas_qua = FigureCanvasKivyAgg(fig_qua)

        self.widget_plot.add_widget(self.canvas_qua)

        #Tries to load old simulation, in case there isn't any, it creates an
        #empty experiment with only psi(t=0)
        print("Trying to load last simulation")
        try:
            self.load_experiment()
        except FileNotFoundError:
            print("Could not find last simulation, creating new one...")
            self.experiment = DSexperiment()
            self.experiment.set_gaussian_psi0(p0x = 150/self.experiment.Lx)
            self.maxP = np.max(self.experiment.Pt)

        self.create_textures()
        self.clock = Clock.schedule_interval(self.update, 1.0 / 30.0)



    def set_language(self, lang):
        self.language = lang
        self.button_1slit.text = self.strings['slit'][self.language]
        self.button_2slits.text = self.strings['slits'][self.language]
        self.button_large.text = self.strings['large'][self.language]
        self.button_medium.text = self.strings['medium'][self.language]
        self.button_small.text = self.strings['small'][self.language]
        self.label_speed.text = self.strings['speed'][self.language]

    def load_experiment(self):
        self.experiment = create_experiment_from_files("{}_{}".format(self.slits, self.slit_size))
        print("Simulation loaded correctly")
        self.computation_done(save = False)
        self.remove_measurements()
        self.experiment.compute_py(force = True)
        aqu.plot(np.arange(-self.experiment.Ly, self.experiment.Ly, self.experiment.dx), self.experiment.py, c = "g", lw = 4)
        aqu.set_xlim(-self.experiment.Ly, self.experiment.Ly)
        aqu.set_ylim(0,np.max(self.experiment.py))
        self.canvas_qua.draw()



    #Drawing functions
    def create_textures(self):
        """
        Creates the textures that will be used (for the wavefunction and for the potential (slits) )
        """
        self.texture_psi = Texture.create(size = self.experiment.Pt[0].shape[::-1], colorfmt = "luminance", bufferfmt = "uint")
        self.texture_V = Texture.create(size = self.experiment.Pt[0].shape[::-1], colorfmt = "rgba", bufferfmt = "uint")

    wall_color = (200, 0, 255)

    def blit_P(self, P):
        """
        This function draws the heatmap for P centered at
        P is a 2d numpy array
        """

        #Basically if white should represent the maximum value of P at each frame
        #or should represent the maximum value of all frames
        if self.normalize_each_frame:
            max = np.max(P)
        else:
            max = self.maxP

        #Stores the P matrix in the texture object
        #this texture is created in the method creature_texture and already has the size
        #It's a gray-scale texture so value must go from 0 to 255 (P/self.maxP)*255
        #It must be an array of unsigned 8bit integers. And also it has to be flattened

        self.texture_psi.blit_buffer( ((P[:,::-1]/max)*255).astype(np.uint8).reshape(P.size), colorfmt = "luminance")

        #Draws walls
        with self.p_rectangle.canvas:
            #Determines the size of the box:
            #Full height
            self.zoom = self.p_rectangle.height/P.shape[0]
            #If full height implies cutting by the sides, it uses full width
            if P.shape[1]*self.zoom > self.p_rectangle.width:
                #Full width
                self.zoom = self.p_rectangle.width/P.shape[1]

            self.wh = P.shape[1]*self.zoom
            self.hh = P.shape[0]*self.zoom

            self.xh = self.p_rectangle.pos[0] + self.p_rectangle.width/2 - self.wh/2
            self.yh = self.p_rectangle.pos[1] + self.p_rectangle.height/2 - self.hh/2

            Color(self.wall_color[0]/255, self.wall_color[1]/255, self.wall_color[2]/255) #Red
            #box wall
            Rectangle(pos = (self.xh-5, self.yh-5), size = (self.wh+10, self.hh+10))

            #Heatmap
            Color(1., 1., 1.) #White
            Rectangle(texture = self.texture_psi, pos = (self.xh, self.yh), size = (self.wh, self.hh))

    def draw_slits(self):
        """
        Draws the slits (heatmap of the potential energy)
        """
        with self.p_rectangle.canvas:
            V = self.experiment.V[:,::-1]
            Vo = self.experiment.Vo

            M = np.zeros((V.shape[0], V.shape[1], 4), dtype = np.uint8)
            for i in range(3):
                M[:,:,i] = (self.wall_color[i]*V/Vo).astype(np.uint8)
            M[:,:,3] = M[:,:,0]

            self.texture_V.blit_buffer( M.reshape(M.size), colorfmt = "rgba")

            Rectangle(texture = self.texture_V, pos = (self.xh, self.yh), size = (self.wh, self.hh))


    def draw_measures(self):
        """
        Draws points representing measures in the main UI
        """

        with self.p_rectangle.canvas:
            scale = self.zoom/self.experiment.dx

            #Measuring screen
            Color(0, 1., 0, 0.25)
            Rectangle(pos = (self.xh + self.wh - self.experiment.mp*self.zoom, self.yh), size = (self.experiment.mw*self.zoom, self.hh))

            Color(0, 1., 0)
            for measure in self.experiment.measurements:
                Ellipse(pos = (self.xh + self.wh - 2*self.experiment.mp*self.zoom + measure[0]*self.zoom , self.yh + measure[1]*self.zoom), size = (self.zoom, self.zoom))

    def computation_update(self, msg, x):
        """
        This is called by the thread computing the simulation
        """
        pass

    def computation_done(self, save = True):
        """
        This is called when the simulation has been completed
        """
        self.frames = self.experiment.Pt.shape[0]
        self.maxP = np.max(self.experiment.Pt)
        self.create_textures()


        if save:
            self.experiment.save_to_files("lastsim")

    def slider_moved(self, a, b):
        Clock.schedule_once(self.reset_speed, 5*60)

    def reset_speed(self, a):
        self.speed_slider.value = 5

    #Playback functions
    def playpause(self):
        self.playing = not self.playing
        if self.playing:
            self.clock = Clock.schedule_interval(self.update, 1.0 / 30.0)
            self.playpause_button.text = "Pause experiment"
        else:
            self.clock.cancel()
            self.playpause_button.text = "Start experiment"

    def change_frame(self):
        self.playing = False

    def measure(self, N = 1):
        #self.beep.play()
        self.experiment.measure(N)
        aqu.cla()
        aqu.hist([-self.experiment.Ly + measure[1]*self.experiment.dx for measure in self.experiment.measurements], bins = 20, normed = True)
        aqu.set_xlim(-self.experiment.Ly, self.experiment.Ly)
        aqu.plot(np.arange(-self.experiment.Ly, self.experiment.Ly, self.experiment.dx), self.experiment.py, c="g", lw = 4)
        self.canvas_qua.draw()


    def remove_measurements(self):
        self.experiment.clear_measurements()

    def button_toggled(self, button, value):
        if button.group == "number":
            if value:
                self.slits = int(button.name)
        elif button.group == "size":
            if value:
                self.slit_size = button.name

        if value:
            self.load_experiment()
        print(self.slits, self.slit_size)

    def update(self, dt):

        self.speed = int(self.speed_slider.value)

        if self.playing:
            self.p_rectangle.canvas.clear()
            self.blit_P(self.experiment.Pt[self.frame])
            self.draw_slits()
            self.draw_measures()
            self.frame = (self.frame+self.speed)

            if self.frame >= self.frames:
                if self.beep:
                    self.beep.play()
                self.measure()
                if self.loop:
                    self.frame = self.frame%self.frames
                else:
                    self.frame = 0

        else:
            self.p_rectangle.canvas.clear()
            self.blit_P(self.experiment.Pt[self.frame])
            self.draw_slits()
            self.draw_measures()
Ejemplo n.º 16
0
class MainWindow(Screen):

    my_map = ObjectProperty()
    data_layer = ObjectProperty()
    tekst = ObjectProperty()
    wykres = ObjectProperty()
    file = ObjectProperty()

    def __init__(self, **kwargs):
        super(MainWindow, self).__init__(**kwargs)
        self.my_map.map_source = "thunderforest-landscape"

    def generuj_trase(self):

        if self.file is None:
            self.show_popup()

        else:
            dane = metody.wczytanie_pliku(self.file)
            self.draw_route(dane[0])
            self.rysuj_wykres(dane)
            self.tekst.text = dane[1]
            fi_sr = dane[0]["lat"].mean() * 180 / pi
            la_sr = dane[0]["lon"].mean() * 180 / pi
            self.my_map.center_on(fi_sr, la_sr)
            self.my_map.zoom = 12

    def rysuj_wykres(self, dane):
        self.fig = plt.figure()
        self.ax1 = self.fig.add_subplot(111)
        self.ax1.set_title("Trasa")
        self.ax1.scatter([dane[0]["lon"] * 180 / pi],
                         [dane[0]["lat"] * 180 / pi],
                         s=6)  #rysowanie trasy
        self.cnv = FigureCanvasKivyAgg(self.fig)
        self.wykres.add_widget(self.cnv)
        self.cnv.draw()  #rysowanie wykresu

    #rysowanie trasy
    def draw_route(self, df):
        self.data_layer = MarkerMapLayer(
        )  #utworzenie warstwy, creating instance of class MarkerMapLayer
        self.my_map.add_layer(self.data_layer)  #dodanie warstwy do mapy

        for i in range(df.shape[0]):
            self.mark_point(lat=float((df.iloc[i, 0]) * 180 / pi),
                            lon=float(df.iloc[i, 1] * 180 / pi),
                            layer=self.data_layer)  #narysowanie trasy

    #rysowanie znacznika - w tym przypadku kropki
    def mark_point(self, lat, lon, layer=None, markerSource="dot.png"):

        if lat != None and lon != None:
            marker = MapMarker(lat=lat, lon=lon,
                               source=markerSource)  #utworzenie markera
            self.my_map.add_marker(marker,
                                   layer=layer)  #dodanie markera do mapy

    def usun_trase(self):

        if self.file is None:
            self.show_popup()

        else:
            self.my_map.remove_layer(self.data_layer)  #usuniecie trasy

    def dismiss_popup(self):
        self._popup.dismiss()

    def show_popup(self):
        show = Okno()

        # Create the popup window
        popupWindow = Popup(title="Blad!",
                            content=show,
                            size_hint=(None, None),
                            size=(400, 200))

        popupWindow.open()  # show the popup

    def load(self, path, filename):
        self.file = filename[0]

        with open(os.path.join(path, filename[0])) as stream:
            with open('nowyplik.gpx', 'w+') as plik:
                plik.write(stream.read())

        self.dismiss_popup()

    def show_load(self):
        content = LoadDialog(load=self.load, cancel=self.dismiss_popup)
        self._popup = Popup(title="Wczytanie pliku",
                            content=content,
                            size_hint=(0.9, 0.9))
        self._popup.open()
Ejemplo n.º 17
0
class QMeasures(Screen):
    """
    Main class. The one passed to the executable class. It has acces to  
    differents parts of the app layout (since it inherits from BoxLayout).
    
    This class consists of three main blocks:
        
        - COMPUTATION of a wave function's evolution on different potentials
        - PLOTTING of this evolution
        - GAME. A game is build on top of this problem.
    
    All functions will be organised with this structure in mind. Nevertheless,
    the core of this class are animation and events flow, managed only
    by a few functions – they actually use the functions from the main blocks.
    
    The animation (events flow) will simply consist of:
        
        - A repeatedly called function (called by Kivy's Clock) that computes
        and plots the evolution of the wave function: PLOTPSIEV.
        - A function called by the player that takes a measure of the position
        of the instantaneous wave function, and carries on all its 
        consequences: MEASURE
        - A function that allows the player to start again after the game is 
        over: RESTART
        - And finally a couple of functions that allow pausing the game and 
        controlling its velocity: PAUSE & CHANGE_VEL
        
    These are the time FLOWING functions.
    
    Before starting the calls of plotpsiev, with Clock: 
        
        - The evolution problem has to be solved 
        - The plots have to be initialized 
        - The game has to be set to the beggining
        - Clock's call
        
    So in init, all of this is done before calling Clock.
    """
    def __init__(self, **kwargs):
        super(QMeasures, self).__init__(**kwargs)  #Runs also the superclass
        #BoxLayout's __init__ function

        #======================== EVOLUTION PROBLEM ===========================
        """                       
        Solving this problems has two parts: finding the EIGENBASIS and 
        eigenvalues of the given hamiltonian (with a given potential), and
        find the COMPONENTS of the intial psi in this basis.
        """

        #SOLVING 1ST PART

        #UNITS
        self.unit_time = 'fs'
        self.unit_energy = 'eV'
        self.unit_long = '$\AA$'
        self.unit_probxlong = '$\AA^{-1}$'

        #CONSTANTS
        self.hbar = 0.6582  #In these general units
        self.m_elec = 0.1316  #Its the m factor explained in eigenparam function
        self.m = self.m_elec  #The name 'm' is the one used inside of eigenparam
        self.dirac_sigma = 0.6

        #DISCRETIZATION
        self.a = -10.
        self.b = 10.
        self.N = 800
        self.deltax = (self.b - self.a) / float(self.N)
        self.mesh = np.linspace(self.a, self.b, self.N + 1)

        #POTENTIAL INITAIL SETTINGS
        self.settings = open('lvl_settings.txt', 'r')
        self.read_settigns()

        #EIGENBASIS
        self.eigenparam()

        #SOLVING 2ND PART

        #PSI INITIAL SETTINGS
        #After every measure
        #        self.p0 = 0.
        self.sigma0 = self.dirac_sigma
        #This first one (even after restarting)
        self.lvl = 1  #psi_init is going to use it
        self.psi_init(apply_cond=True)

        #COMPONENTS & ENERGY
        self.comp()
        self.energy = np.sum(np.abs(self.compo)**2 * self.evals)

        #============================ PLOTTING ================================
        """
        Includes the creation of all plotted objects (legend, axis, ...)
        but the updated data. This will happen in the plotting function. Here 
        we should assign the canvas (created with FigureCanvasKivyAgg) to the 
        'box' where it will be plotted in the app with:
        self.box/panel_id.add_widget(self.FigureCanvasKivyAggs_name)
        
        There are four plots: background (BKG), psi (PSI), potential (POT) and
        a gray map for visualization (VISU). They are arranged in a (2,1) grid: 
        first 3  plots on the top of the grid and the other bellow.
        
        Those three together share the x axis and are created in an specific 
        order so important content don't overlap. That is: bkg, psi and pot.
        
        Moreover, pot has an extra plot, energy line. And psi as well, two 
        arrows for visualization of the measure.
        """

        #COLORS
        self.zonecol_red = '#AA3939'
        self.zonecol_green = '#7B9F35'
        self.potcol = '#226666'
        self.potalpha = 0.5
        self.orange = '#AA6C39'
        self.cmap_name = 'gray'
        self.energycol = '#AA8439'
        self.b_arrow_color = '#C0C0C0'
        self.u_arrow_color = '#582A72'

        #LIMITS
        self.pot_tlim = 50
        self.pot_blim = 0
        self.psi_tlim = 1.7
        self.psi_blim = 0
        Dpot = self.pot_tlim - self.pot_blim
        Dpsi = self.psi_tlim - self.psi_blim
        self.dcoord_factor = Dpot / Dpsi

        #FIGURE
        self.axis_on = True
        #        plt.show(block=False)
        self.main_fig = plt.figure()
        self.main_fig.patch.set_facecolor('black')
        self.main_canvas = FigureCanvasKivyAgg(self.main_fig)  #Passed to kv
        self.box1.add_widget(self.main_canvas)
        self.gs = gridspec.GridSpec(2,
                                    1,
                                    height_ratios=[7, 1],
                                    hspace=0.1,
                                    bottom=0.05,
                                    top=0.90)  #Subplots grid

        #BACKGROUND
        #Their axes are going to be as psi's, since their default position
        #suits us. The title is going to be used as xaxis label.
        self.bkg_twin = plt.subplot(self.gs[0])
        self.bkg_twin.axis([self.a, self.b, self.psi_blim, self.psi_tlim])
        figheight = self.main_fig.get_figheight()  #In inches (100 p = 1 inch)
        self.bkg_twin.set_title('x [' + self.unit_long + ']',
                                color='white',
                                pad=0.05 * figheight * 100,
                                fontsize=10)  #pad in p
        self.bkg_twin.set_ylabel('Probability [' + self.unit_probxlong + ']',
                                 color='white')
        self.bkg_twin.tick_params(axis='x',
                                  labelbottom=False,
                                  labeltop=True,
                                  bottom=False,
                                  top=True)
        self.bkg_twin.tick_params(colors='white')
        self.bkg_twin.set_facecolor('black')
        self.fill_bkg()
        #Arrows (first drawn transparent just to create the instance)
        self.b_arrow = self.bkg_twin.arrow(0, 0, 0, 0, alpha=0)
        self.u_arrow = self.bkg_twin.arrow(0, 0, 0, 0, alpha=0)

        #POTENTIAL
        self.pot_twin = self.bkg_twin.twinx()
        self.pot_twin.axis([self.a, self.b, self.pot_blim, self.pot_tlim])
        self.pot_twin.set_ylabel('Potential [' + self.unit_energy + ']',
                                 color='white')
        self.pot_twin.tick_params(axis='y', colors='white')
        self.pot_twin.set_facecolor('black')
        self.pot_data, = self.pot_twin.plot(self.mesh,
                                            self.potential,
                                            color=self.potcol)
        #Energy
        self.E_data, = self.pot_twin.plot(self.mesh,
                                          np.zeros_like(self.mesh) +
                                          self.energy,
                                          color=self.energycol,
                                          ls='--',
                                          lw=2)

        #VISUAL
        self.visuax = plt.subplot(self.gs[1])
        self.num_visu = len(self.mesh)  #Can't be greater than the # of indices
        self.inter_visu = 'gaussian'
        self.visuax.axis('off')
        step = int(len(self.psi) / self.num_visu)  #num_visu points in gray map
        self.visu_im = self.visuax.imshow([self.psi2[::step]],
                                          aspect='auto',
                                          interpolation=self.inter_visu,
                                          cmap=self.cmap_name)

        #FIRST DRAW
        #This 'tight' needs to be at the end so it considers all objects drawn
        self.main_fig.tight_layout()  #Fills all available space
        self.main_canvas.draw()

        #============================== GAME ==================================

        #IMAGES
        path = os.path.dirname(os.path.abspath(__file__))
        self.gameover_imgdata = mpimg.imread(path + str('/gameover_img.jpg'))
        self.heart_img = 'heart_img.jpg'
        self.skull_img = 'skull_img.jpg'

        #GAME VARIABLES
        self.max_lives = 10  #If changed, kv's file needs to be changed as well
        self.lives = self.max_lives
        self.lives_sources()
        self.lvl = 1
        self.dummy = False

        #KEYBOARD
        #       request_keyboard returns an instance that represents the events on
        #       the keyboard. It can give two events (witch we can bind to functions).
        #       Furthermore, each event comes with some input arguments:
        #       on_key_down    --      keycode, text, modifiers
        #       on_key_up      --      keycode
        #       Using the functions bind and unbind on this instance we can bind or
        #       unbind the instance event with a callback/function AND passing the
        #       above arguments into the function.
        #       When using request_keyboard a callback/function must be given. It is
        #       going to be called when releasing/closing the keyboard (shutting the
        #       app, or reasigning the keyboard with another request_keyboard). It
        #       usualy unbinds everything bound.
        self._keyboard = Window.request_keyboard(self._keyboard_closed, self)
        self._keyboard.bind(on_key_down=self._on_keyboard_down)

        #TIME
        self.plt_time = 0.
        self.plt_dt = 1. / 30.
        self.plt_vel_factor = 16  #Factor in dt
        self.pause_state = True  #Begins paused

        #LABELS
        self.label_vel.text = 'Velocity \n    ' + str(
            self.plt_vel_factor) + 'X'

        #============================== CLOCK =================================
        """
        Here all animation will be happening. The plotting function definied in
        the proper section will be called several times per second. The given 
        frame rate is going to be delayed (or not) depending on how many things
        happen in one frame. 
        """
        #'THE' CORE
        Clock.schedule_interval(self.plotpsiev, 1 / 30)

    ###########################################################################
    #                            'FLOW' FUNCTIONS                             #
    ###########################################################################
    """
    - plotpsiev
    - measure
    - restart
    - skip_lvl
    - change_vel
    - pause
    """

    #PLOTPSIEV
    def plotpsiev(self, dt):
        """
        Function to be called in the animation loop (clock.schedule_interval),
        it has to have dt as an argument. Here first is computed psi(t), then
        the data is updated in psi_data and finally it draws on the canvas. 
        This parameter dt is not the actual time, its only the real time 
        interval between calls. The time is obtained with self.plt_time.
        """
        if not self.pause_state:  #Only evolve plt_time if we are unpaused
            #TIME
            self.plt_time += self.plt_vel_factor * self.plt_dt  #Time step
            t = self.plt_time

            #COMPUTE PSIEV(t). We do it with two steps (given t).
            #_1_.
            #Column vector containing the product between component and
            #exponential factor. 1st build array ary and then col. matrix 'mtx'
            ary_compexp = self.compo * \
                        np.exp(np.complex(0.,-1.)*self.evals*t/(50*self.hbar))
            mtx_compexp = np.matrix(np.reshape(ary_compexp, (self.N + 1, 1)))
            #_2_.
            #Psi(t)
            col_psi = self.evect * mtx_compexp  #Matrix product

            #UPDATE DATA. Since col_psi is a column vector (N+1,1) and we
            #need to pass a list, we reshape and make it an array.
            self.psi = np.array(np.reshape(col_psi, self.N + 1))[0]
            self.psi2 = np.abs(self.psi)**2

            #BKG
            self.fill_bkg()
            self.b_arrow.set_alpha(np.exp(-t / 10))
            self.u_arrow.set_alpha(np.exp(-t / 10))

            #VISUAL PLOT
            self.visu_im.remove()
            step = int(len(self.psi) / self.num_visu)  #Same as in the 1st plot
            self.visu_im = self.visuax.imshow([self.psi2[::step]],
                                              aspect='auto',
                                              interpolation=self.inter_visu,
                                              cmap=self.cmap_name)

        #DRAW
        #(keeps drawing even if there hasn't been an update)
        self.main_canvas.draw()

    def measure(self):
        """
        Triggered from the kivy file. It takes the actual psi(t), generates 
        the probability distribution and picks the new value for mu. A new 
        initial wave function is created with a small sigma witch represents
        the delta post measure. The time needs to be reset to zero after 
        measuring. Finally, calls comp() and now plotpsiev() has everything it
        needs to continue plotting.
        
        Schedule:
            - Get instant probability
            - Pick new mu0
            - Reset time
            - New sigma 
            - Check zone:
                OUT
                * Substract points AND/OR change lives
                    !(extra with lives game mode)
                    ! Check if any lives left
                    ! Pauses the game
                    ! Game over image
                    ! Disables measures (buton and spacebar)
                    ! Enable restart button
                * New psi (psi_init)
                * New comp (eigenbassis still the same)
                * Draw(data) psi and fill
                * Fill bkg (WITH PSI, tho still the same redzone)
                * Redraw visuplot
                IN
                * Add points
                * New level
                * Read new level
                * New pot
                * Eigenparam
                * New psi (psi_init)
                * New comp (eigenbassis still the same)
                * Draw(data) psi and fill
                * Fill bkg (WITH PSI, with new redzone)
                * Update new redzone (while filling)
                * Redraw visuplot
            - Update labels
        """
        prob = self.deltax * self.psi2  #Get instant probability
        prob /= sum(prob)
        self.mu0 = np.random.choice(self.mesh, p=prob)  #Pick new random mu0
        if self.dummy:
            self.mu0 = self.mesh[np.argmax(prob)]

        self.measure_arrow()
        self.plt_time = 0.  #Reset time
        self.sigma0 = self.dirac_sigma  #New sigma

        if self.mu0 in self.redzone:  #OUT
            self.lives -= 1
            self.lives_sources()
            self.psi_init()
            self.comp()
            if self.lives <= 0:  #GAME OVER
                self.pause_state = True
                self.pause_btn.text = 'Play'
                self.GMO_img = self.pot_twin.imshow(self.gameover_imgdata,
                                                    aspect='auto',
                                                    extent=[-7.5, 7.5, 0, 40])
                self.measure_btn.disabled = True
                self.pause_btn.disabled = True
                self.restart_btn.disabled = False
                self._keyboard.release()
            self.fill_bkg()
            #VISUAL PLOT
            self.visu_im.remove()
            step = int(len(self.psi) / self.num_visu)  #Same as in the 1st plot
            self.visu_im = self.visuax.imshow([self.psi2[::step]],
                                              aspect='auto',
                                              interpolation=self.inter_visu,
                                              cmap=self.cmap_name)

        else:  #IN
            self.lvl += 1  #Read new lvl
            self.label_lvl.text = 'Level ' + str(self.lvl)
            self.read_settigns()
            self.pot_data.set_data(self.mesh, self.potential)
            #Eigenparam
            self.eigenparam()
            self.psi_init(apply_cond=True)
            self.comp()
            self.fill_bkg()
            #VISUAL PLOT
            self.visu_im.remove()
            step = int(len(self.psi) / self.num_visu)  #Same as in the 1st plot
            self.visu_im = self.visuax.imshow([self.psi2[::step]],
                                              aspect='auto',
                                              interpolation=self.inter_visu,
                                              cmap=self.cmap_name)

        self.energy = np.sum(np.abs(self.compo)**2 * self.evals)
        self.E_data.set_data(self.mesh, self.energy)

    def skip_lvl(self):
        """
        Skips the current level. Does exactly what measure does, but always
        passes the level.
        """
        prob = self.deltax * self.psi2  #Get instant probability
        self.mu0 = np.random.choice(self.mesh, p=prob)  #Pick new random mu0
        if self.dummy:
            self.mu0 = self.mesh[np.argmax(prob)]
        self.b_arrow.remove()
        self.u_arrow.remove()
        self.b_arrow = self.bkg_twin.arrow(0, 0, 0, 0, alpha=0)
        self.u_arrow = self.bkg_twin.arrow(0, 0, 0, 0, alpha=0)
        self.plt_time = 0.  #Reset time
        self.sigma0 = self.dirac_sigma  #New sigma
        self.lvl += 1
        self.label_lvl.text = 'Level ' + str(self.lvl)
        self.read_settigns()
        self.pot_data.set_data(self.mesh, self.potential)
        #Eigenparam
        self.eigenparam()
        self.psi_init(apply_cond=True)
        self.comp()
        self.fill_bkg()
        #VISUAL PLOT
        self.visu_im.remove()
        step = int(len(self.psi) / self.num_visu)  #Same as in the 1st plot
        self.visu_im = self.visuax.imshow([self.psi2[::step]],
                                          aspect='auto',
                                          interpolation=self.inter_visu,
                                          cmap=self.cmap_name)
        #ENERGY
        self.energy = np.sum(np.abs(self.compo)**2 * self.evals)
        self.E_data.set_data(self.mesh, self.energy)

    #RESTART
    def restart(self):
        """
        After the game is lost, sets everything ready to start again:
            - Clear game over image
            - Lvl 1
            - Lives and its images to max_lives
            - Pauses again (in cas we unpaused it during game over)
            - Starts reading the settings file again (lvl 1)
            - New pot (init)
            - Eigenparam
            - New mu0 (initial mu)
            - New psi (sigma already dirac's)
            - New comp 
            - Fill psi
            - Bkg fill + update redzone
            - Redraw visuplot
            - Enables measures (button and spacebar)
            - Disables restart 
            - Clears arrows
        """
        self.GMO_img.remove()
        self.lvl = 1
        self.lives = self.max_lives
        self.lives_sources()
        self.pause_state = True
        self.pause_btn.text = 'Play'
        self.settings.close()  #We close and open again to start reading again
        self.settings = open('lvl_settings.txt', 'r')
        self.read_settigns()
        self.pot_data.set_data(self.mesh, self.potential)
        self.eigenparam()
        self.psi_init(apply_cond=True)
        self.comp()
        self.redzone = np.array([])
        self.fill_bkg()
        self.visu_im.remove()
        step = int(len(self.psi) / self.num_visu)  #Same as in the 1st plot
        self.visu_im = self.visuax.imshow([self.psi2[::step]],
                                          aspect='auto',
                                          interpolation=self.inter_visu,
                                          cmap=self.cmap_name)

        self.measure_btn.disabled = False
        self.pause_btn.disabled = False
        self.request_KB()
        self.restart_btn.disabled = True
        self.energy = np.sum(np.abs(self.compo)**2 * self.evals)
        self.E_data.set_data(self.mesh, self.energy)
        self.b_arrow.remove()
        self.u_arrow.remove()
        self.b_arrow = self.bkg_twin.arrow(0, 0, 0, 0, alpha=0)
        self.u_arrow = self.bkg_twin.arrow(0, 0, 0, 0, alpha=0)

    def change_vel(self):
        """
        Changes the factor in the plot time diferential.
        """
        self.plt_vel_factor *= 2
        if self.plt_vel_factor > 32:
            self.plt_vel_factor = 1
        #Label in kivy file
        self.label_vel.text = 'Velocity \n    ' + str(
            self.plt_vel_factor) + 'X'

    def pause(self):
        """
        Changes the pause state from true to false and viceversa.
        """
        #        self.measure_btn.unbind(on_press = self.measure)
        if self.pause_state == True:  #Unpause
            self.pause_state = False
            self.pause_btn.text = 'Pause'
        else:
            self.pause_state = True  #Pause
            self.pause_btn.text = 'Play'

    ###########################################################################
    #                            COMPUTING FUNCTIONS                          #
    ###########################################################################
    """
    - eigenparam
    - comp
    - read_setings
    - psi_init
    - shift_psi
    """

    def eigenparam(self):
        """
        Compute a vector with the eigenvalues(eV) and another with the 
        eigenvectors ((Aº)**-1/2) of the quantum hamiltonian with potential 
        [self.potential [eV]] (each column is an eigenvector with [N]+1 
        components). 
        
           H · phi = E · phi  ;  H = -(1/2m)(d**2/dx**2) + poten(x)
                    m := mass / hbar**2  [(eV·Aº**2)**-1]
    
        
        It solves the 1D time-independent Schrödinger equation for the given 
        potential (self.potential) inside of a box [a(Aº), b(Aº)], with 
        [N] intervals. 
        """
        #Dividing the ab segment in N intervals leave us with a (N+1)x(N+1)
        #hamiltonian, where indices 0 and N correspond to the potentials
        #barriers. The hamiltonian operator has 3 non-zero diagonals (the main
        #diagonal, and the ones next to it), with the following elements.
        semi_diag = np.full(self.N, -1. / (2. * self.m * self.deltax**2))
        main_diag = self.potential + 1. / (self.m * self.deltax**2)
        #Although we keep these walls here, no change seems to happen if we
        #remove them (if we don't assign these values)
        main_diag[0] += 1000000000  #Potentials barriers
        main_diag[self.N] += 1000000000
        self.evals, self.evect = spLA.eigh_tridiagonal(main_diag,
                                                       semi_diag,
                                                       check_finite=False)

        #Normalization. Used trapezoids method formula and that sum(evect**2)=1
        factors =1/np.sqrt(self.deltax * \
                               (1. - np.abs(self.evect[0,:])**2/2. - \
                                               np.abs(self.evect[-1,:])**2/2.))
        #Normalized vectors (* here multiplies each factor element by each
        #evect column)
        self.evect = self.evect * factors

    def comp(self):
        """
        Generates the initial wave function's components on the eigenbasis 
        stored in self.compo.
        """
        #Compute psi components
        phipsi = np.transpose(np.transpose(np.conj(self.evect)) * self.psi)
        self.compo = self.deltax * (np.sum(phipsi, axis = 0) \
                                            - phipsi[0,:]/2. - phipsi[-1,:]/2.)

    def read_settigns(self):
        """
        Reads file settings, assigns parameters and initializes the potentials.
        First element chooses potential:
            
            - If 0: HARMONIC
            Line: 0, mu0, dx, k, **redzone 
            
            - If 1: DOUBLE WELL (20*[HARMONIC + CG*GAUSSIAN])
            Line: 1, mu0, dx, k, mu, sigma, CG, **redzone
            
            - If 2: TRIPLE WELL (20*[HARMONIC + CG1*GAUSSIAN + CG2*GAUSSIAN2])
            Line: 2, mu0, dx, k, mu1, sigma1, CG1, mu2, sigma2, CG2, **redzone
            
            - If 3 WOOD-SAXON
            Line: 3, mu0, H, R, a, **redzone
            
            - If 4: DOUBLE WOOD-SAXON
            Line: 4, mu0, H1, R1, a1, H2, R2, a2, **redzone
            
        Where mu0 is the position where to start the new psi. If no position 
        wants to be specified, then mu0 = 100 (checked in psi_init)
        Number of arguments have to be passed to the realted variable.
        """
        self.lvl_set = np.array(eval(self.settings.readline().strip()))
        #HARMONIC
        if self.lvl_set[0] == 0:
            dx, k = self.lvl_set[2:3 + 1]
            self.potential = 20 * 0.5 * k * (self.mesh - dx)**2
            self.fill_start_i = 4
        #DOUBLE WELL
        elif self.lvl_set[0] == 1:
            dx, k, mu, sigma, CG = self.lvl_set[2:6 + 1]
            self.potential = 20*(\
                    0.5*k*(self.mesh - dx)**2
                    +\
                    CG/np.sqrt(2*np.pi*sigma**2)*\
                    np.exp(-(self.mesh-mu)**2/(2.*sigma**2)))
            self.fill_start_i = 7
        #TRIPLE WELL
        elif self.lvl_set[0] == 2:
            dx, k, mu1, sigma1, CG1, mu2, sigma2, CG2 = self.lvl_set[2:9 + 1]
            self.potential = 20*(\
                    0.5*k*(self.mesh - dx)**2
                    +\
                    CG1/np.sqrt(2*np.pi*sigma1**2)*\
                    np.exp(-(self.mesh-mu1)**2/(2.*sigma1**2))
                    +\
                    CG2/np.sqrt(2*np.pi*sigma2**2)*\
                    np.exp(-(self.mesh-mu2)**2/(2.*sigma2**2)))
            self.fill_start_i = 10
        #WOOD-SAXON
        elif self.lvl_set[0] == 3:
            H, R, a = self.lvl_set[2:4 + 1]
            self.potential = -H / (1 + np.exp((abs(self.mesh) - R) / a)) + H
            self.fill_start_i = 5
        #DOUBLE WOOD-SAXON
        elif self.lvl_set[0] == 4:
            H1, R1, a1, H2, R2, a2 = self.lvl_set[2:7 + 1]
            WS1 = -H1 / (1 + np.exp((abs(self.mesh) - R1) / a1)) + H1
            WS2 = H2 / (1 + np.exp((abs(self.mesh) - R2) / a2))
            self.potential = WS1 + WS2
            self.fill_start_i = 8

        else:
            print('ERROR: Bad code word for potential (1st element in line).')

    def psi_init(self, apply_cond=False):
        """
        Creates the initial wave function, a gaussian packet in general. The 
        output's shape is the same as mesh. If apply_cond is True, some 
        specific conditions are checked and applied. Usually, it will be True
        after starting a new level for the first time.
        """
        if apply_cond:
            #Conditions on the starting postiion
            new_mu0 = self.lvl_set[1]
            if new_mu0 != 100:
                self.mu0 = new_mu0
                print('New mu0: ', new_mu0)
            #Other conditions
            if self.lvl == 10:
                #Starting at the middle maximum and paused
                self.pause_state = True
                self.pause_btn.text = 'Play'
            if self.lvl == 22:
                #Speeding up
                self.plt_vel_factor *= 1.5
                self.label_vel.text = 'Velocity \n    ' + \
                                    str(int(self.plt_vel_factor)) +'X'

        #First we generate the shape of a gaussian, no need for norm. constants
        #We then normalize using the integration over the array.
        self.psi = np.sqrt(\
                         np.exp(-(self.mesh-self.mu0)**2/(2.*self.sigma0**2)))#\
        #                                  *np.exp(np.complex(0.,-1.)*self.p0*self.mesh)
        prob_psi = np.abs(self.psi)**2
        self.psi *= 1. / np.sqrt(self.deltax*\
                      (np.sum(prob_psi) - prob_psi[0]/2. - prob_psi[-1]/2.))
        self.psi2 = np.abs(self.psi)**2

    def shift_psi(self, x):
        """
        Makes psi a given eigenvector of the hamiltonian but shifted a
        certain amount x. Negative x means shift to the left and vicerversa.
        """
        if x == 0 or x <= self.a or x >= self.b:
            self.psi = self.evect[:, 2]
            self.psi2 = np.abs(self.psi)**2

            return

        #compute how many indices are in x:
        n = int(abs(x) / self.deltax)
        if x < 0:
            eigen = self.evect[:, 0]
            app = np.append(eigen, np.zeros(n))
            self.psi = app[-(self.N + 1):]
            self.psi2 = np.abs(self.psi)**2

        if x > 0:
            eigen = self.evect[:, 0]
            app = np.append(np.zeros(n), eigen)
            self.psi = app[:self.N + 1]
            self.psi2 = np.abs(self.psi)**2

        self.psi *= 1. / np.sqrt(self.deltax*\
                      (np.sum(self.psi2) - self.psi2[0]/2. - self.psi2[-1]/2.))
        self.psi2 = np.abs(self.psi)**2

    ###########################################################################
    #                             PLOTTING FUNCTIONS                          #
    ###########################################################################
    """
    - fill_bkg
    - measure_arrow
    """

    def fill_bkg(self):
        """
        Fills background in bkg axis, bkg_twin, with red and green zones of the
        current self.lvl_set. It fills above self.psi2. Keeps track of 
        the red points in self.redzone. We take every other border from the 
        file and fill the prev. zone(red) and the following zone (green). 
        Last one added a side (red).
        """
        self.bkg_twin.collections.clear(
        )  #Clear before so we don't draw on top
        self.redzone = np.array([])
        prev = self.a

        for i in range(self.fill_start_i, len(self.lvl_set) - 1, 2):
            #Index
            prev_index = int((prev - self.a) // self.deltax)
            index = int((self.lvl_set[i] - self.a) // self.deltax)
            nxt_index = int((self.lvl_set[-1] - self.a) // self.deltax)

            #Red
            bot = (self.psi2)[prev_index:index + 1]  #Psi line
            top = np.zeros_like(bot) + 2.
            redzone = self.mesh[prev_index:index + 1]  #+1 due to slice
            potential = self.potential[prev_index:index +
                                       1] / self.dcoord_factor
            self.redzone = np.append(self.redzone, redzone)
            self.bkg_twin.fill_between(redzone,
                                       bot,
                                       potential,
                                       where=np.less(bot, potential),
                                       facecolor=self.potcol)  #Potential
            self.bkg_twin.fill_between(redzone,
                                       np.maximum(potential, bot),
                                       top,
                                       facecolor=self.zonecol_red)  #Red

            #Green
            bot = (self.psi2)[index - 1:nxt_index + 2]
            top = np.zeros_like(bot) + 2.
            greenzone = self.mesh[index - 1:nxt_index + 2]  #(")
            potential = self.potential[index - 1:nxt_index +
                                       2] / self.dcoord_factor
            self.bkg_twin.fill_between(greenzone,
                                       bot,
                                       potential,
                                       where=np.less(bot, potential),
                                       facecolor=self.potcol)  #Potential
            self.bkg_twin.fill_between(greenzone,
                                       np.maximum(potential, bot),
                                       top,
                                       facecolor=self.zonecol_green)
            #Green
            #Looping by giving the new prev position
            prev = self.mesh[int(
                (self.lvl_set[i + 1] - self.a) // self.deltax)]

        #Last zone red
        bot = (self.psi2)[nxt_index:]
        top = np.zeros_like(bot) + 2.
        redzone = self.mesh[nxt_index:]
        potential = self.potential[nxt_index:] / self.dcoord_factor
        self.redzone = np.append(self.redzone, redzone)
        self.bkg_twin.fill_between(redzone,
                                   bot,
                                   potential,
                                   where=np.less(bot, potential),
                                   facecolor=self.potcol)  #Potential
        self.bkg_twin.fill_between(redzone,
                                   np.maximum(potential, bot),
                                   top,
                                   facecolor=self.zonecol_red)  #Red

    def measure_arrow(self):
        """
        Draws the annotation (line) on the measured mu0. Two annotations: line
        from bottom to the probilibity we got, and another from there to the 
        max probability.
        """
        #Clears before running
        self.b_arrow.remove()
        self.u_arrow.remove()

        prob = self.psi2  #%·Å^-1
        m_prob = prob[int((self.mu0 - self.a) / self.deltax)]
        max_prob = np.max(prob)

        self.b_arrow = self.bkg_twin.arrow(self.mu0,
                                           0,
                                           0,
                                           m_prob,
                                           color=self.b_arrow_color,
                                           width=0.25,
                                           head_width=0.001,
                                           head_length=0.001)

        self.u_arrow = self.bkg_twin.arrow(self.mu0,
                                           m_prob,
                                           0,
                                           max_prob - m_prob,
                                           color=self.u_arrow_color,
                                           width=0.25,
                                           head_width=0.001,
                                           head_length=0.001)

    ###########################################################################
    #                              GAME FUNCTIONS                             #
    ###########################################################################
    """
    - lives_sources
    - _keyboard_closed
    - request_KB
    - _on_keyboard_down 
    - dummy_mode
    """

    def lives_sources(self):
        """
        Replaces every live image source: having N lives, replaces live1 to
        liveN with 'heart_img.jpg', and live(N+1) to live(max_lives) with 
        'skull_img.jpg'. So, when changing the amount of lives, this has to be
        called.
        """
        for live_spot in range(1, self.max_lives + 1):
            live_name = 'live' + str(live_spot)
            img = self.ids[live_name]  #self.ids is a dict of all id(s) from kv
            if live_spot <= self.lives:  #Heart
                img.source = self.heart_img
            else:
                img.source = self.skull_img

    def _keyboard_closed(self):
        """
        Actions taken when keyboard is released/closed. Unbinding and 
        'removing' the _keyboard.
        """
        print('keyboard released')
        self._keyboard.unbind(on_key_down=self._on_keyboard_down)
        #Is happening that clicking on the box (outside any button) relases the
        #keyboard. This can be 'fixed' adding a button that requests the
        #keyboard again.
        self._keyboard = None

    def request_KB(self):
        """
        Requesting and binding keyboard again, only if it has been released.
        """
        if self._keyboard == None:  #It has been released
            self._keyboard = Window.request_keyboard(self._keyboard_closed,
                                                     self)
            self._keyboard.bind(on_key_down=self._on_keyboard_down)
        else:
            pass

    def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
        """
        Bind to the event on_key_down, whenever keyboard is used this function
        will be called. So, it contains every function related to the keyboard.
        """
        #We still want the escape to close the window, so diong the following,
        #pressing twice escape will close it.
        if keycode[1] == 'spacebar':
            self.measure()
        return

    def dummy_mode(self):
        """
        Changes the game mode to picking the most probable value for x instead
        of randomly. Changes the controlling variable and updates button label.
        """
        if self.dummy:  # Using dummy. Change mode
            self.dummy = False
            self.dummy_btn.text = 'Helping:\n    Off'
        else:  # Not using dummy. Change mode
            self.dummy = True
            self.dummy_btn.text = 'Helping:\n    On'

    def axis_off(self):
        """
        Turns off or on the axis.
        """
        if self.axis_on:  #They are on, switching them off
            self.bkg_twin.axis('off')  #Difference in dt when on or off: 0.02
            self.bkg_twin.set_title(' ')
            self.pot_twin.axis('off')  #Difference in dt when on or off: 0.01
            self.axis_on = False
        else:
            self.bkg_twin.axis('on')
            figheight = self.main_fig.get_figheight(
            )  #In inches (100p = 1inch)
            self.bkg_twin.set_title('x [' + self.unit_long + ']',
                                    color='white',
                                    pad=0.05 * figheight * 100,
                                    fontsize=10)  #pad in p
            self.pot_twin.axis('on')
            self.axis_on = True
Ejemplo n.º 18
0
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
Ejemplo n.º 19
0
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)